From 6c77425ac2a4e582cf60f71e2b62e2b3d2fd2401 Mon Sep 17 00:00:00 2001 From: Skick Date: Thu, 15 Dec 2022 11:47:19 +0700 Subject: [PATCH] fix: thumbnail error when getting album/playlist --- src/__test__/index.test.ts | 12 ++++-------- src/index.ts | 32 ++++++++++++++++++++------------ 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/__test__/index.test.ts b/src/__test__/index.test.ts index 2d2af98..6b967dd 100644 --- a/src/__test__/index.test.ts +++ b/src/__test__/index.test.ts @@ -2,18 +2,16 @@ import { SpotifyPlugin } from ".."; test.todo("Validate Options"); test.todo("SpotifyPlugin#play()"); -test("SpotifyPlugin#validate()", () => { +test("SpotifyPlugin#validate()", async () => { const { validate } = new SpotifyPlugin(); const validUrls = [ - "https://open.spotify.com/artist/3FwYnbtGNt8hJfjNuOfpeG?si=d4c1d832636c4bb1", "https://open.spotify.com/album/5Gu0Ldddj2f6a0q5gitIok?si=781b3339b2bc4015", "https://open.spotify.com/track/6Fbsn9471Xd0vVsMWwhePh?si=f992e1fe1f714674", "https://open.spotify.com/playlist/37i9dQZEVXbLdGSmz6xilI?si=28a3d4be17304ade", ]; - validUrls.forEach(url => { - expect(validate(url)).resolves.toBe(true); - }); + await Promise.all(validUrls.map(url => expect(validate(url)).resolves.toBe(true))); const invalidUrls = [ + "https://open.spotify.com/artist/3FwYnbtGNt8hJfjNuOfpeG?si=d4c1d832636c4bb1", "https://open.spotify.com/show/6vcyNclFEFyS2pVSKFEWJo?si=893aa44bd6504cf9", "https://open.spotify.com/episode/42wDq6xhm7vbqD3glD1JSd?si=6016d24bf1b54793", "https://open.spotify.com/not-a-type/42wDq6xhm7vbqD3glD1JSd?si=6016d24bf1b54793", @@ -21,7 +19,5 @@ test("SpotifyPlugin#validate()", () => { "https://www.youtube.com/watch?v=fzcIk6zN-M4", "not a url", ]; - invalidUrls.forEach(url => { - expect(validate(url)).resolves.toBe(false); - }); + await Promise.all(invalidUrls.map(url => expect(validate(url)).resolves.toBe(false))); }); diff --git a/src/index.ts b/src/index.ts index b0628d5..ab700f8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,7 @@ import { CustomPlugin, DisTubeError, Playlist, Song, checkInvalidKey } from "dis import type { VoiceBasedChannel } from "discord.js"; import type { PlayOptions, PlaylistInfo, Queue, SearchResult } from "distube"; -const SUPPORTED_TYPES = ["album", "artist", "playlist", "track"]; +const SUPPORTED_TYPES = ["album", "playlist", "track"]; const API = new SpotifyWebApi(); const spotify = SpotifyUrlInfo(fetch); let expirationTime = 0; @@ -22,6 +22,7 @@ declare type SpotifyPluginOptions = { type Falsy = undefined | null | false | 0 | ""; const isTruthy = (x: T | Falsy): x is T => Boolean(x); +type ClassMethods = { [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never }[keyof T]; const refreshAPIToken = async () => { if (expirationTime <= Date.now() - 60000) { @@ -46,7 +47,7 @@ const getItems = async (data: any): Promise => { }) ).body; } catch (e: any) { - process.emitWarning(`${e?.body?.message}`, "SpotifyAPI"); + process.emitWarning(`${e?.body?.message}`, "SpotifyApi"); process.emitWarning("There is a Spotify API error, max songs of Spotify playlist is 100.", "SpotifyPlugin"); break; } @@ -55,7 +56,8 @@ const getItems = async (data: any): Promise => { return items; }; -const getAPI = (method: string, ...args: any) => (API)[method](...args).then((r: any) => r.body); +const getAPI = >(method: T, ...args: Parameters) => + (API[method])(...args).then((r: any) => r.body); const getDataWithAPI = async (url: string) => { const parsedURL = parseSpotifyURI(url); @@ -72,10 +74,6 @@ const getDataWithAPI = async (url: string) => { data = await getAPI("getAlbum", id); data.tracks = await getAPI("getAlbumTracks", id, { limit: 50 }); break; - case "artist": - data = await getAPI("getArtist", id); - data.tracks = (await getAPI("getArtistTopTracks", id, "US")).tracks; - break; case "playlist": data = await getAPI("getPlaylist", id); data.tracks = await getAPI("getPlaylistTracks", id, { limit: 100 }); @@ -100,21 +98,31 @@ export class SpotifyPlugin extends CustomPlugin { checkInvalidKey(options, ["parallel", "emitEventsAfterFetching", "api"], "SpotifyPluginOptions"); this.parallel = options.parallel ?? true; if (typeof this.parallel !== "boolean") { - throw new DisTubeError("INVALID_TYPE", "boolean", this.parallel, "parallel"); + throw new DisTubeError("INVALID_TYPE", "boolean", this.parallel, "SpotifyPluginOptions.parallel"); } this.emitEventsAfterFetching = options.emitEventsAfterFetching ?? false; if (typeof this.emitEventsAfterFetching !== "boolean") { - throw new DisTubeError("INVALID_TYPE", "boolean", this.emitEventsAfterFetching, "emitEventsAfterFetching"); + throw new DisTubeError( + "INVALID_TYPE", + "boolean", + this.emitEventsAfterFetching, + "SpotifyPluginOptions.emitEventsAfterFetching", + ); } API.setAccessToken(""); if (options.api !== undefined && (typeof options.api !== "object" || Array.isArray(options.api))) { throw new DisTubeError("INVALID_TYPE", ["object", "undefined"], options.api, "api"); } else if (options.api) { if (typeof options.api.clientId !== "string") { - throw new DisTubeError("INVALID_TYPE", "string", options.api.clientId, "api.clientId"); + throw new DisTubeError("INVALID_TYPE", "string", options.api.clientId, "SpotifyPluginOptions.api.clientId"); } if (typeof options.api.clientSecret !== "string") { - throw new DisTubeError("INVALID_TYPE", "string", options.api.clientSecret, "api.clientSecret"); + throw new DisTubeError( + "INVALID_TYPE", + "string", + options.api.clientSecret, + "SpotifyPluginOptions.api.clientSecret", + ); } API.setClientId(options.api.clientId); API.setClientSecret(options.api.clientSecret); @@ -163,7 +171,7 @@ export class SpotifyPlugin extends CustomPlugin { await DT.play(voiceChannel, result, options); } else { const name = data.name; - const thumbnail = data.images[0]?.url; + const thumbnail = (data.coverArt?.sources || data.images)?.[0]?.url; const queries: string[] = (await getItems(data)) .map(item => { const track = item.track || item;