{"version":3,"sources":["../src/API.ts","../src/index.ts"],"sourcesContent":["import SpotifyInfo from \"spotify-url-info\";\nimport SpotifyWebApi from \"spotify-web-api-node\";\nimport { fetch } from \"undici\";\nimport { DisTubeError, isTruthy } from \"distube\";\nimport { parse as parseSpotifyUri } from \"spotify-uri\";\n\nconst SUPPORTED_TYPES = [\"album\", \"playlist\", \"track\", \"artist\"] as const;\n\nconst WEB_API = new SpotifyWebApi();\nconst INFO = SpotifyInfo(fetch);\n\ntype Track = {\n  type: \"track\";\n  id: string;\n  name: string;\n  artists: { name: string }[];\n  thumbnail?: string;\n  duration: number;\n};\n\ntype EmbedList = {\n  type: \"album\" | \"playlist\" | \"artist\";\n  title: string;\n  subtitle: string;\n  uri: string;\n  trackList: { title: string; subtitle: string; uri: string; duration: number }[];\n  coverArt?: {\n    sources?: { url: string }[];\n  };\n};\n\ntype DataList = {\n  type: string;\n  name: string;\n  thumbnail?: string;\n  url: string;\n  tracks: Track[];\n};\n\ntype Album = DataList & { type: \"album\" };\ntype Playlist = DataList & { type: \"playlist\" };\ntype Artist = DataList & { type: \"artist\" };\ntype TrackList = Album | Playlist | Artist;\ntype Data = Track | TrackList;\n\nlet firstWarning1 = true;\nlet firstWarning2 = true;\n\nexport const apiError = (e: any) =>\n  new DisTubeError(\n    \"SPOTIFY_API_ERROR\",\n    `The URL is private or unavailable.${e?.body?.error?.message ? `\\nDetails: ${e.body.error.message}` : \"\"}${\n      e?.statusCode ? `\\nStatus code: ${e.statusCode}.` : \"\"\n    }`,\n  );\n\ntype APITrackInfo = SpotifyApi.TrackObjectSimplified & { album: SpotifyApi.AlbumObjectSimplified };\nclass APITrack implements Track {\n  type: \"track\";\n  id: string;\n  name: string;\n  artists: { name: string }[];\n  thumbnail?: string;\n  duration: number;\n  constructor(info: APITrackInfo) {\n    this.type = \"track\";\n    this.id = info.id;\n    this.name = info.name;\n    this.artists = info.artists;\n    this.thumbnail = info.album?.images?.[0]?.url;\n    this.duration = info.duration_ms;\n  }\n}\n\nconst mergeAlbumTrack = (\n  album: SpotifyApi.AlbumObjectSimplified,\n  track: SpotifyApi.TrackObjectSimplified,\n): APITrackInfo => {\n  (<APITrackInfo>track).album = album;\n  return <APITrackInfo>track;\n};\n\nexport class API {\n  private _hasCredentials = false;\n  private _expirationTime = 0;\n  private _tokenAvailable = false;\n  topTracksCountry = \"US\";\n\n  constructor(clientId?: string, clientSecret?: string, topTracksCountry?: string) {\n    if (clientId && clientSecret) {\n      this._hasCredentials = true;\n      WEB_API.setClientId(clientId);\n      WEB_API.setClientSecret(clientSecret);\n    }\n    if (topTracksCountry) {\n      if (!/^[A-Z]{2}$/.test(topTracksCountry)) throw new Error(\"Invalid region code\");\n      this.topTracksCountry = topTracksCountry;\n    }\n  }\n\n  isSupportedTypes(type: string): type is (typeof SUPPORTED_TYPES)[number] {\n    return SUPPORTED_TYPES.includes(<any>type);\n  }\n\n  async refreshToken() {\n    if (Date.now() < this._expirationTime) return;\n    if (this._hasCredentials) {\n      try {\n        const { body } = await WEB_API.clientCredentialsGrant();\n        WEB_API.setAccessToken(body.access_token);\n        this._expirationTime = Date.now() + body.expires_in * 1000 - 5_000;\n      } catch (e) {\n        if (firstWarning1) {\n          firstWarning1 = false;\n          this._hasCredentials = false;\n          /* eslint-disable no-console */\n          console.warn(e);\n          console.warn(\"[SPOTIFY_PLUGIN_API] Cannot get token from your credentials. Try scraping token instead.\");\n          /* eslint-enable no-console */\n        }\n      }\n    }\n    if (!this._hasCredentials) {\n      const response = await fetch(\"https://open.spotify.com/\");\n      const body = await response.text();\n      const token = body.match(/\"accessToken\":\"(.+?)\"/)?.[1];\n      if (!token) {\n        this._tokenAvailable = false;\n        if (firstWarning2) {\n          firstWarning2 = false;\n          /* eslint-disable no-console */\n          console.warn(\n            \"[SPOTIFY_PLUGIN_API] Cannot get token from scraping. \" +\n              \"Cannot fetch more than 100 tracks from a playlist or album.\",\n          );\n          /* eslint-enable no-console */\n        }\n        return;\n      }\n      WEB_API.setAccessToken(token);\n      const expiration = body.match(/\"accessTokenExpirationTimestampMs\":(\\d+)/)?.[1];\n      if (expiration) this._expirationTime = Number(expiration) - 5_000;\n      // Else: token should be valid right now, but don't know when it expires\n    }\n    this._tokenAvailable = true;\n  }\n\n  parseUrl(url: string) {\n    return parseSpotifyUri(url);\n  }\n\n  getData(url: `${string}/track/${string}`): Promise<Track>;\n  getData(url: `${string}/album/${string}`): Promise<Album>;\n  getData(url: `${string}/playlist/${string}`): Promise<Playlist>;\n  getData(url: `${string}/artist/${string}`): Promise<Artist>;\n  getData(url: string): Promise<Data>;\n  async getData(url: string): Promise<Data> {\n    const { type, id } = this.parseUrl(url);\n\n    if (!id) throw new DisTubeError(\"SPOTIFY_API_INVALID_URL\", \"Invalid URL\");\n    if (!this.isSupportedTypes(type)) throw new DisTubeError(\"SPOTIFY_API_UNSUPPORTED_TYPE\", \"Unsupported URL type\");\n\n    await this.refreshToken();\n    if (type === \"track\") {\n      if (!this._tokenAvailable) {\n        return INFO.getData(url);\n      }\n      try {\n        const { body } = await WEB_API.getTrack(id);\n        return new APITrack(body);\n      } catch (e) {\n        throw apiError(e);\n      }\n    }\n    if (!this._tokenAvailable) {\n      const data = (await INFO.getData(url)) as EmbedList;\n      const thumbnail = data.coverArt?.sources?.[0]?.url;\n      return {\n        type,\n        name: data.title,\n        thumbnail,\n        url,\n        tracks: data.trackList.map(i => ({\n          type: \"track\",\n          id: this.parseUrl(i.uri).id,\n          name: i.title,\n          artists: [{ name: i.subtitle }],\n          duration: i.duration,\n          thumbnail,\n        })),\n      };\n    }\n    try {\n      const { body } =\n        await WEB_API[type === \"album\" ? \"getAlbum\" : type === \"playlist\" ? \"getPlaylist\" : \"getArtist\"](id);\n      return {\n        type,\n        name: body.name,\n        thumbnail: body.images?.[0]?.url,\n        url: body.external_urls?.spotify,\n        tracks: (await this.#getTracks(body)).filter(t => t?.type === \"track\").map(t => new APITrack(t)),\n      };\n    } catch (e) {\n      throw apiError(e);\n    }\n  }\n\n  async #getTracks(\n    data: SpotifyApi.SingleAlbumResponse | SpotifyApi.SinglePlaylistResponse | SpotifyApi.SingleArtistResponse,\n  ): Promise<APITrackInfo[]> {\n    switch (data.type) {\n      case \"artist\": {\n        return (await WEB_API.getArtistTopTracks(data.id, this.topTracksCountry)).body.tracks;\n      }\n      case \"album\": {\n        const tracks = await this.#getPaginatedItems(data);\n        return tracks.map(t => mergeAlbumTrack(data, t));\n      }\n      case \"playlist\": {\n        return (await this.#getPaginatedItems(data)).map(i => i.track).filter(isTruthy);\n      }\n    }\n  }\n\n  #getPaginatedItems(data: SpotifyApi.SingleAlbumResponse): Promise<SpotifyApi.TrackObjectSimplified[]>;\n  #getPaginatedItems(data: SpotifyApi.SinglePlaylistResponse): Promise<SpotifyApi.PlaylistTrackObject[]>;\n  async #getPaginatedItems(data: SpotifyApi.SingleAlbumResponse | SpotifyApi.SinglePlaylistResponse) {\n    const items: (SpotifyApi.TrackObjectSimplified | SpotifyApi.PlaylistTrackObject)[] = data.tracks.items;\n    const isPlaylist = data.type === \"playlist\";\n    const limit = isPlaylist ? 100 : 50;\n    const method = isPlaylist ? \"getPlaylistTracks\" : \"getAlbumTracks\";\n    while (data.tracks.next) {\n      await this.refreshToken();\n      data.tracks = (await WEB_API[method](data.id, { offset: data.tracks.offset + data.tracks.limit, limit })).body;\n      items.push(...data.tracks.items);\n    }\n    return items;\n  }\n}\n","import { API } from \"./API\";\nimport { DisTubeError, InfoExtractorPlugin, Playlist, type ResolveOptions, Song, checkInvalidKey } from \"distube\";\n\nexport type SpotifyPluginOptions = {\n  api?: {\n    clientId?: string;\n    clientSecret?: string;\n    topTracksCountry?: string;\n  };\n};\n\nexport class SpotifyPlugin extends InfoExtractorPlugin {\n  api: API;\n  constructor(options: SpotifyPluginOptions = {}) {\n    super();\n    if (typeof options !== \"object\" || Array.isArray(options)) {\n      throw new DisTubeError(\"INVALID_TYPE\", [\"object\", \"undefined\"], options, \"SpotifyPluginOptions\");\n    }\n    checkInvalidKey(options, [\"api\"], \"SpotifyPluginOptions\");\n    if (options.api !== undefined && (typeof options.api !== \"object\" || Array.isArray(options.api))) {\n      throw new DisTubeError(\"INVALID_TYPE\", [\"object\", \"undefined\"], options.api, \"api\");\n    } else if (options.api) {\n      if (options.api.clientId && typeof options.api.clientId !== \"string\") {\n        throw new DisTubeError(\"INVALID_TYPE\", \"string\", options.api.clientId, \"SpotifyPluginOptions.api.clientId\");\n      }\n      if (options.api.clientSecret && typeof options.api.clientSecret !== \"string\") {\n        throw new DisTubeError(\n          \"INVALID_TYPE\",\n          \"string\",\n          options.api.clientSecret,\n          \"SpotifyPluginOptions.api.clientSecret\",\n        );\n      }\n      if (options.api.topTracksCountry && typeof options.api.topTracksCountry !== \"string\") {\n        throw new DisTubeError(\n          \"INVALID_TYPE\",\n          \"string\",\n          options.api.topTracksCountry,\n          \"SpotifyPluginOptions.api.topTracksCountry\",\n        );\n      }\n    }\n    this.api = new API(options.api?.clientId, options.api?.clientSecret, options.api?.topTracksCountry);\n  }\n\n  validate(url: string) {\n    if (typeof url !== \"string\" || !url.includes(\"spotify\")) return false;\n    try {\n      const parsedURL = this.api.parseUrl(url);\n      if (!parsedURL.type || !this.api.isSupportedTypes(parsedURL.type)) return false;\n      return true;\n    } catch (error) {\n      return false;\n    }\n  }\n\n  async resolve<T>(url: string, options: ResolveOptions<T>): Promise<Song<T> | Playlist<T>> {\n    const data = await this.api.getData(url);\n    if (data.type === \"track\") {\n      return new Song(\n        {\n          plugin: this,\n          source: \"spotify\",\n          playFromSource: false,\n          name: data.name,\n          id: data.id,\n          url: `https://open.spotify.com/track/${data.id}`,\n          thumbnail: data.thumbnail,\n          uploader: {\n            name: data.artists.map(a => a.name).join(\", \"),\n          },\n          duration: data.duration / 1000,\n        },\n        options,\n      );\n    }\n    return new Playlist(\n      {\n        source: \"spotify\",\n        name: data.name,\n        url: data.url,\n        thumbnail: data.thumbnail,\n        songs: data.tracks.map(\n          t =>\n            new Song(\n              {\n                plugin: this,\n                source: \"spotify\",\n                id: t.id,\n                playFromSource: false,\n                name: t.name,\n                thumbnail: t.thumbnail,\n                uploader: {\n                  name: t.artists.map(a => a.name).join(\", \"),\n                },\n                url: `https://open.spotify.com/track/${t.id}`,\n                duration: t.duration / 1000,\n              },\n              options,\n            ),\n        ),\n      },\n      options,\n    );\n  }\n\n  createSearchQuery<T>(song: Song<T>): string {\n    return `${song.name} ${song.uploader.name}`;\n  }\n\n  getRelatedSongs() {\n    return [];\n  }\n}\n\nexport default SpotifyPlugin;\n"],"mappings":"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","names":["DisTubeError","DisTubeError"]}