magmastream 2.10.3-dev.2 → 2.10.3

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.
@@ -83,7 +83,7 @@ export declare abstract class AutoPlayUtils {
83
83
  * @param platform The source to get recommended tracks from.
84
84
  * @returns An array of recommended tracks.
85
85
  */
86
- static getRecommendedTracksFromSource(track: Track, platform: AutoPlayPlatform): Promise<Track[]>;
86
+ static getRecommendedTracksFromSource(track: Track, platform: AutoPlayPlatform, node?: import("./Node").Node): Promise<Track[]>;
87
87
  /**
88
88
  * Searches for a track using the manager and returns resolved tracks.
89
89
  * @param query The search query (artist - title).
@@ -63,7 +63,7 @@ class TrackUtils {
63
63
  if (typeof track !== "object" || track === null)
64
64
  return false;
65
65
  const trackRecord = track;
66
- return REQUIRED_TRACK_KEYS.every((key) => typeof trackRecord[key] === "string");
66
+ return REQUIRED_TRACK_KEYS.every((key) => (key === "uri" ? typeof trackRecord[key] === "string" || trackRecord[key] === null : typeof trackRecord[key] === "string"));
67
67
  }
68
68
  /**
69
69
  * Checks if the provided argument is a valid Track array.
@@ -97,17 +97,32 @@ class TrackUtils {
97
97
  }
98
98
  try {
99
99
  const sourceNameMap = {
100
+ amazonmusic: "AmazonMusic",
101
+ anghami: "Anghami",
100
102
  applemusic: "AppleMusic",
103
+ audiomack: "Audiomack",
101
104
  audius: "Audius",
102
105
  bandcamp: "Bandcamp",
106
+ bilibili: "Bilibili",
103
107
  deezer: "Deezer",
108
+ eternalbox: "EternalBox",
109
+ flowery: "Flowery",
110
+ gaana: "Gaana",
111
+ googledrive: "GoogleDrive",
112
+ googletts: "GoogleTTS",
113
+ iheartradio: "IHeartRadio",
104
114
  jiosaavn: "Jiosaavn",
115
+ lastfm: "LastFM",
116
+ netease: "Netease",
105
117
  soundcloud: "SoundCloud",
106
118
  spotify: "Spotify",
107
119
  tidal: "Tidal",
108
120
  youtube: "YouTube",
109
121
  vkmusic: "VKMusic",
122
+ nicovideo: "NicoVideo",
123
+ pandora: "Pandora",
110
124
  qobuz: "Qobuz",
125
+ shazam: "Shazam",
111
126
  http: "Http",
112
127
  tts: "Tts",
113
128
  clypit: "Clypit",
@@ -131,14 +146,14 @@ class TrackUtils {
131
146
  uri: data.info.uri,
132
147
  artworkUrl: data.info?.artworkUrl ?? null,
133
148
  sourceName: sourceNameMap[data.info?.sourceName?.toLowerCase() ?? ""] ?? data.info?.sourceName,
134
- thumbnail: data.info.uri.includes("youtube") ? `https://img.youtube.com/vi/${data.info.identifier}/default.jpg` : null,
149
+ thumbnail: data.info.uri?.includes("youtube") ? `https://img.youtube.com/vi/${data.info.identifier}/default.jpg` : null,
135
150
  displayThumbnail(size = "default") {
136
151
  const finalSize = SIZES.find((s) => s === size) ?? "default";
137
- return this.uri.includes("youtube") ? `https://img.youtube.com/vi/${data.info.identifier}/${finalSize}.jpg` : null;
152
+ return this.uri?.includes("youtube") ? `https://img.youtube.com/vi/${data.info.identifier}/${finalSize}.jpg` : null;
138
153
  },
139
154
  requester: requester,
140
155
  pluginInfo: data.pluginInfo,
141
- customData: {},
156
+ customData: data.userData ?? {},
142
157
  isAutoplay: isAutoplay,
143
158
  };
144
159
  track.displayThumbnail = track.displayThumbnail.bind(track);
@@ -180,7 +195,7 @@ class TrackUtils {
180
195
  return track;
181
196
  track.displayThumbnail = function (size = "default") {
182
197
  const finalSize = SIZES.find((s) => s === size) ?? "default";
183
- return this.uri.includes("youtube") ? `https://img.youtube.com/vi/${this.identifier}/${finalSize}.jpg` : null;
198
+ return this.uri?.includes("youtube") ? `https://img.youtube.com/vi/${this.identifier}/${finalSize}.jpg` : null;
184
199
  }.bind(track);
185
200
  return track;
186
201
  }
@@ -228,7 +243,14 @@ class AutoPlayUtils {
228
243
  // Iterate over autoplay platforms in order of priority
229
244
  for (const platform of autoPlaySearchPlatforms) {
230
245
  if (enabledSources.includes(platform)) {
231
- const recommendedTracks = await this.getRecommendedTracksFromSource(track, platform);
246
+ let recommendedTracks;
247
+ try {
248
+ recommendedTracks = await this.getRecommendedTracksFromSource(track, platform, node);
249
+ }
250
+ catch (error) {
251
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[AUTOPLAY] Failed to fetch recommendations from ${platform}: ${error instanceof Error ? error.message : String(error)}`);
252
+ continue;
253
+ }
232
254
  // If tracks are found, return them immediately
233
255
  if (recommendedTracks.length > 0) {
234
256
  return recommendedTracks;
@@ -316,8 +338,12 @@ class AutoPlayUtils {
316
338
  * @param platform The source to get recommended tracks from.
317
339
  * @returns An array of recommended tracks.
318
340
  */
319
- static async getRecommendedTracksFromSource(track, platform) {
341
+ static async getRecommendedTracksFromSource(track, platform, node = this.manager.useableNode) {
320
342
  const requester = track.requester;
343
+ if (!track.uri)
344
+ return [];
345
+ if (!node)
346
+ return [];
321
347
  const parsedURL = new URL(track.uri);
322
348
  switch (platform) {
323
349
  case Enums_1.AutoPlayPlatform.Spotify: {
@@ -334,8 +360,8 @@ class AutoPlayUtils {
334
360
  // return match ? match[1] : null;
335
361
  // };
336
362
  // const identifier = `sprec:seed_artists=${extractSpotifyArtistID(track.pluginInfo.artistUrl)}&seed_tracks=${track.identifier}`;
337
- const identifier = `sprec:mix:track:${track.identifier}`;
338
- const recommendedResult = (await this.manager.useableNode.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
363
+ const identifier = node.isNodeLink ? `sprec:seed_tracks=${track.identifier}` : `sprec:mix:track:${track.identifier}`;
364
+ const recommendedResult = (await node.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
339
365
  const tracks = this.buildTracksFromResponse(recommendedResult, requester);
340
366
  return tracks;
341
367
  }
@@ -348,7 +374,7 @@ class AutoPlayUtils {
348
374
  track = resolvedTrack;
349
375
  }
350
376
  const identifier = `dzrec:${track.identifier}`;
351
- const recommendedResult = (await this.manager.useableNode.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
377
+ const recommendedResult = (await node.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
352
378
  const tracks = this.buildTracksFromResponse(recommendedResult, requester);
353
379
  return tracks;
354
380
  }
@@ -412,14 +438,14 @@ class AutoPlayUtils {
412
438
  }
413
439
  case Enums_1.AutoPlayPlatform.YouTube: {
414
440
  const allowedYouTubeHosts = ["youtube.com", "youtu.be"];
415
- const hasYouTubeURL = allowedYouTubeHosts.some((url) => track.uri.includes(url));
441
+ const hasYouTubeURL = allowedYouTubeHosts.some((url) => track.uri?.includes(url));
416
442
  let videoID = null;
417
443
  if (hasYouTubeURL) {
418
- videoID = track.uri.split("=").pop();
444
+ videoID = track.uri?.split("=").pop() ?? null;
419
445
  }
420
446
  else {
421
447
  const resolvedTrack = await this.resolveFirstTrackFromQuery(`${track.author} - ${track.title}`, Enums_1.SearchPlatform.YouTube, requester);
422
- if (!resolvedTrack)
448
+ if (!resolvedTrack?.uri)
423
449
  return [];
424
450
  videoID = resolvedTrack.uri.split("=").pop();
425
451
  }
@@ -431,7 +457,7 @@ class AutoPlayUtils {
431
457
  do {
432
458
  randomIndex = Math.floor(Math.random() * 23) + 2;
433
459
  searchURI = `https://www.youtube.com/watch?v=${videoID}&list=RD${videoID}&index=${randomIndex}`;
434
- } while (track.uri.includes(searchURI));
460
+ } while (track.uri?.includes(searchURI));
435
461
  const resolvedTracks = await this.resolveTracksFromQuery(searchURI, Enums_1.SearchPlatform.YouTube, requester);
436
462
  const filteredTracks = resolvedTracks.filter((resolvedTrack) => resolvedTrack.uri !== track.uri);
437
463
  return filteredTracks;
@@ -445,7 +471,7 @@ class AutoPlayUtils {
445
471
  track = resolvedTrack;
446
472
  }
447
473
  const identifier = `tdrec:${track.identifier}`;
448
- const recommendedResult = (await this.manager.useableNode.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
474
+ const recommendedResult = (await node.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
449
475
  const tracks = this.buildTracksFromResponse(recommendedResult, requester);
450
476
  return tracks;
451
477
  }
@@ -458,7 +484,7 @@ class AutoPlayUtils {
458
484
  track = resolvedTrack;
459
485
  }
460
486
  const identifier = `vkrec:${track.identifier}`;
461
- const recommendedResult = (await this.manager.useableNode.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
487
+ const recommendedResult = (await node.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
462
488
  const tracks = this.buildTracksFromResponse(recommendedResult, requester);
463
489
  return tracks;
464
490
  }
@@ -471,7 +497,7 @@ class AutoPlayUtils {
471
497
  track = resolvedTrack;
472
498
  }
473
499
  const identifier = `qbrec:${track.identifier}`;
474
- const recommendedResult = (await this.manager.useableNode.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
500
+ const recommendedResult = (await node.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
475
501
  const tracks = this.buildTracksFromResponse(recommendedResult, requester);
476
502
  return tracks;
477
503
  }
@@ -484,7 +510,7 @@ class AutoPlayUtils {
484
510
  track = resolvedTrack;
485
511
  }
486
512
  const identifier = `ymrec:${track.identifier}`;
487
- const recommendedResult = (await this.manager.useableNode.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
513
+ const recommendedResult = (await node.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
488
514
  const tracks = this.buildTracksFromResponse(recommendedResult, requester);
489
515
  return tracks;
490
516
  }
@@ -513,6 +539,7 @@ class AutoPlayUtils {
513
539
  case Enums_1.LoadTypes.Playlist:
514
540
  return searchResult.playlist.tracks;
515
541
  case Enums_1.LoadTypes.Track:
542
+ case Enums_1.LoadTypes.Episode:
516
543
  case Enums_1.LoadTypes.Search:
517
544
  case Enums_1.LoadTypes.Short:
518
545
  return searchResult.tracks;
@@ -548,6 +575,7 @@ class AutoPlayUtils {
548
575
  case Enums_1.LoadTypes.Playlist:
549
576
  return searchResult.playlist.tracks[0] || null;
550
577
  case Enums_1.LoadTypes.Track:
578
+ case Enums_1.LoadTypes.Episode:
551
579
  case Enums_1.LoadTypes.Search:
552
580
  case Enums_1.LoadTypes.Short:
553
581
  return searchResult.tracks[0] || null;
@@ -575,6 +603,7 @@ class AutoPlayUtils {
575
603
  if (TrackUtils.isErrorOrEmptySearchResult(recommendedResult))
576
604
  return [];
577
605
  switch (recommendedResult.loadType) {
606
+ case Enums_1.LoadTypes.Episode:
578
607
  case Enums_1.LoadTypes.Track: {
579
608
  const data = recommendedResult.data;
580
609
  if (!this.isTrackData(data)) {
@@ -739,7 +768,20 @@ class PlayerUtils {
739
768
  karaoke: player.filters.karaoke ?? null,
740
769
  rotation: player.filters.rotation ?? null,
741
770
  timescale: player.filters.timescale ?? null,
771
+ tremolo: player.filters.tremoloOptions ?? null,
742
772
  vibrato: player.filters.vibrato ?? null,
773
+ channelMix: player.filters.channelMix ?? null,
774
+ lowPass: player.filters.lowPass ?? null,
775
+ highpass: player.filters.highpass ?? null,
776
+ echo: player.filters.echo ?? null,
777
+ chorus: player.filters.chorus ?? null,
778
+ compressor: player.filters.compressor ?? null,
779
+ flanger: player.filters.flanger ?? null,
780
+ phaser: player.filters.phaser ?? null,
781
+ phonograph: player.filters.phonograph ?? null,
782
+ spatial: player.filters.spatial ?? null,
783
+ tape: player.filters.tape ?? null,
784
+ pluginFilters: player.filters.pluginFilters ?? {},
743
785
  reverb: player.filters.reverb ?? null,
744
786
  volume: player.filters.volume ?? 1.0,
745
787
  bassBoostlevel: player.filters.bassBoostlevel ?? null,
@@ -37,10 +37,11 @@ function managerCheck(options, isWrapper = false) {
37
37
  }
38
38
  // Validate defaultSearchPlatform option
39
39
  if (typeof defaultSearchPlatform !== "undefined") {
40
- if (!Object.values(Enums_1.SearchPlatform).includes(defaultSearchPlatform)) {
40
+ const validSearchPlatforms = [...Object.values(Enums_1.SearchPlatform), ...Object.values(Enums_1.NodeLinkSearchPlatform), ...Object.values(Enums_1.NodeLinkRecommendationPlatform)];
41
+ if (!validSearchPlatforms.includes(defaultSearchPlatform)) {
41
42
  throw new MagmastreamError_1.MagmaStreamError({
42
43
  code: Enums_1.MagmaStreamErrorCode.MANAGER_INVALID_CONFIG,
43
- message: `Manager option "defaultSearchPlatform" must be one of: ${Object.values(Enums_1.SearchPlatform).join(", ")}.`,
44
+ message: `Manager option "defaultSearchPlatform" must be one of: ${validSearchPlatforms.join(", ")}.`,
44
45
  context: { option: "defaultSearchPlatform", value: defaultSearchPlatform },
45
46
  });
46
47
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magmastream",
3
- "version": "2.10.3-dev.2",
3
+ "version": "2.10.3",
4
4
  "description": "A user-friendly Lavalink client designed for NodeJS.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",