From 49481b928e7883f00628a4f08c4e73f6a254a686 Mon Sep 17 00:00:00 2001 From: Neil Richter Date: Sun, 25 Jun 2023 19:36:09 +0200 Subject: [PATCH] feat: artists API --- src/api/albums.ts | 2 +- src/api/artists.ts | 63 +++++++++++++++++++++++++++++++++++++++++++++ src/api/client.ts | 5 +++- src/api/index.ts | 3 ++- src/api/users.ts | 6 +++-- src/types/album.ts | 16 +++++++++++- src/types/artist.ts | 34 +++++++++++++++++++++++- 7 files changed, 122 insertions(+), 7 deletions(-) create mode 100644 src/api/artists.ts diff --git a/src/api/albums.ts b/src/api/albums.ts index b7765cd..d0e98aa 100644 --- a/src/api/albums.ts +++ b/src/api/albums.ts @@ -1,9 +1,9 @@ import { ApiPart } from './api.part' -import type { SimplifiedTrackObject } from '@/types' // eslint-disable-next-line unused-imports/no-unused-imports import type { Market, PaginatedResults } from '@/types/common' import type { AlbumObject, GetAlbumsOptions, SavedAlbumObject, SimplifiedAlbumObject } from '@/types/album' +import type { SimplifiedTrackObject } from '@/types/track' export class AlbumsAPI extends ApiPart { /** diff --git a/src/api/artists.ts b/src/api/artists.ts new file mode 100644 index 0000000..01f5b24 --- /dev/null +++ b/src/api/artists.ts @@ -0,0 +1,63 @@ +import { ApiPart } from './api.part' +import type { SimplifiedAlbumObject } from '@/types/album' +import type { ArtistObject, GetArtistAlbumsOptions } from '@/types/artist' +import type { TrackObject } from '@/types/track' + +// eslint-disable-next-line unused-imports/no-unused-imports +import type { Market, PaginatedResults } from '@/types/common' + +export class ArtistsApi extends ApiPart { + /** + * Get Spotify catalog information for a single artist identified by their unique Spotify ID. + * @param artistId The [Spotify ID](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids) for the artist. + */ + public getArtist(artistId: string): Promise { + return this.$fetch(`/artists/${artistId}`) + } + + /** + * Get Spotify catalog information for several artists based on their Spotify IDs. + * @param artistIds A list of the [Spotify IDs](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids) + * for the artists. + * @max `50` IDs. + */ + public getArtists(artistIds: string[]): Promise<{ artists: ArtistObject[] }> { + return this.$fetch<{ artists: ArtistObject[] }>('/artists', { + query: { + ids: artistIds.join(','), + }, + }) + } + + /** + * Get Spotify catalog information about an artist's albums. + * @param artistId The [Spotify ID](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids) for the artist. + */ + public getArtistAlbums(artistId: string, opts: GetArtistAlbumsOptions = {}): Promise> { + return this.$fetch>(`/artists/${artistId}/albums`, { + query: opts, + }) + } + + /** + * + * @param artistId The [Spotify ID](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids) for the artist. + * @param market {@link Market} An [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. If a country code is specified, + * only content that is available in that market will be returned. + */ + public getArtistTopTracks(artistId: string, market?: string): Promise<{ tracks: TrackObject[] }> { + return this.$fetch<{ tracks: TrackObject[] }>(`/artists/${artistId}/top-tracks`, { + query: { + market, + }, + }) + } + + /** + * Get Spotify catalog information about artists similar to a given artist. Similarity is based on analysis of the Spotify community's listening history. + * @param artistId The [Spotify ID](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids) for the artist. + */ + public getRelatedArtists(artistId: string): Promise<{ artists: ArtistObject[] }> { + return this.$fetch<{ artists: ArtistObject[] }>(`/artists/${artistId}/related-artists`) + } +} diff --git a/src/api/client.ts b/src/api/client.ts index 5ebcae8..a7da1f2 100644 --- a/src/api/client.ts +++ b/src/api/client.ts @@ -1,6 +1,6 @@ import type { $Fetch } from 'ofetch' import { Headers, ofetch } from 'ofetch' -import { AlbumsAPI, UsersApi } from '.' +import { AlbumsAPI, ArtistsApi, UsersApi } from '.' export class SpotifyClient { private token: null | string = null @@ -19,6 +19,7 @@ export class SpotifyClient { }) this.albums = new AlbumsAPI(this.$fetch) + this.artists = new ArtistsApi(this.$fetch) this.users = new UsersApi(this.$fetch) } @@ -30,5 +31,7 @@ export class SpotifyClient { public albums: AlbumsAPI + public artists: ArtistsApi + public users: UsersApi } diff --git a/src/api/index.ts b/src/api/index.ts index 9a4c833..1c91418 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,2 +1,3 @@ -export * from './users' export * from './albums' +export * from './artists' +export * from './users' diff --git a/src/api/users.ts b/src/api/users.ts index 3a4bbca..09a3019 100644 --- a/src/api/users.ts +++ b/src/api/users.ts @@ -1,6 +1,8 @@ import { ApiPart } from './api.part' -import { ResourceType } from '@/types' -import type { ArtistObject, CursorResults, PaginatedResults, TrackObject } from '@/types' +import { ResourceType } from '@/types/common' +import type { CursorResults, PaginatedResults } from '@/types/common' +import type { ArtistObject } from '@/types/artist' +import type { TrackObject } from '@/types/track' import type { CurrentUserGetFollowedArtistsOptions, CurrentUserProfile, CurrentUserTopItemsOptions, UserProfile } from '@/types/users' export class UsersApi extends ApiPart { diff --git a/src/types/album.ts b/src/types/album.ts index df6bba6..b9fbd2a 100644 --- a/src/types/album.ts +++ b/src/types/album.ts @@ -1,5 +1,5 @@ -import type { ArtistObject, SimplifiedArtistObject } from './artist' import type { CopyrightsObject, CursorResults, ExternalUrlObject, ImageObject, Market } from './common' +import type { ArtistObject, SimplifiedArtistObject } from './artist' import type { SimplifiedTrackObject } from './track' export interface AlbumObject { @@ -159,10 +159,24 @@ export type SimplifiedAlbumObject = Pick< } export interface GetAlbumsOptions { + /** + * The maximum number of items to return. + * @default `20` + * @min `1` + * @max `50` + */ limit?: number + /** + * The index of the first item to return. Use with limit to get the next set of items. + * @default `0` (the first item). + */ offset?: number + /** + * An [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. If a country code is specified, + * only content that is available in that market will be returned. + */ market?: Market } diff --git a/src/types/artist.ts b/src/types/artist.ts index 8ebe3f8..beaafad 100644 --- a/src/types/artist.ts +++ b/src/types/artist.ts @@ -1,4 +1,4 @@ -import type { ExternalUrlObject, FollowersObject, ImageObject } from './common' +import type { ExternalUrlObject, FollowersObject, ImageObject, Market } from './common' export interface ArtistObject { /** @@ -57,3 +57,35 @@ export interface ArtistObject { } export type SimplifiedArtistObject = Pick + +export interface GetArtistAlbumsOptions { + /** + * A comma-separated list of keywords that will be used to filter the response. If not supplied, all album types will be returned. + * Valid values are: + * - album + * - single + * - appears_on + * - compilation + */ + include_groups?: 'album' | 'single' | 'appears_on' | 'compilation' + + /** + * An [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. If a country code is specified, + * only content that is available in that market will be returned. + */ + market?: Market + + /** + * The maximum number of items to return. + * @default `20` + * @min `1` + * @max `50` + */ + limit?: number + + /** + * The index of the first item to return. Use with limit to get the next set of items. + * @default `0` (the first item). + */ + offset?: number +}