Skip to content

Commit

Permalink
feat: episodes API
Browse files Browse the repository at this point in the history
  • Loading branch information
noook committed Jul 24, 2023
1 parent 661e337 commit 1f03119
Show file tree
Hide file tree
Showing 7 changed files with 258 additions and 9 deletions.
6 changes: 3 additions & 3 deletions src/api/audiobooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export class AudiobooksApi extends ApiPart {

/**
* Save one or more audiobooks to the current Spotify user's library.
* @param ids A list of the [Spotify IDs]([Spotify ID](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids)).
* @param ids A list of the [Spotify IDs](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids).
* @max `50` IDs.
* @scope `user-library-modify`
*/
Expand All @@ -71,7 +71,7 @@ export class AudiobooksApi extends ApiPart {

/**
* Remove one or more audiobooks to the current Spotify user's library.
* @param ids A list of the [Spotify IDs]([Spotify ID](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids)).
* @param ids A list of the [Spotify IDs](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids).
* @max `50` IDs.
* @scope `user-library-modify`
*/
Expand All @@ -86,7 +86,7 @@ export class AudiobooksApi extends ApiPart {

/**
* Check if one or more audiobooks are already saved in the current Spotify user's library.
* @param ids A list of the [Spotify IDs]([Spotify ID](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids)).
* @param ids A list of the [Spotify IDs](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids).
* @max `50` IDs.
* @scope `user-library-read`
*/
Expand Down
5 changes: 4 additions & 1 deletion src/api/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { $Fetch } from 'ofetch'
import { Headers, ofetch } from 'ofetch'
import { AlbumsApi, ArtistsApi, AudiobooksApi, CategoriesApi, ChaptersApi, GenresApi, MarketsApi, PlayerApi, PlaylistsApi, SearchApi, UsersApi } from '.'
import { AlbumsApi, ArtistsApi, AudiobooksApi, CategoriesApi, ChaptersApi, EpisodesApi, GenresApi, MarketsApi, PlayerApi, PlaylistsApi, SearchApi, UsersApi } from '.'

export class SpotifyClient {
private token: null | string = null
Expand All @@ -23,6 +23,7 @@ export class SpotifyClient {
this.audiobooks = new AudiobooksApi(this.$fetch)
this.categories = new CategoriesApi(this.$fetch)
this.chapters = new ChaptersApi(this.$fetch)
this.episodes = new EpisodesApi(this.$fetch)
this.genres = new GenresApi(this.$fetch)
this.markets = new MarketsApi(this.$fetch)
this.player = new PlayerApi(this.$fetch)
Expand All @@ -47,6 +48,8 @@ export class SpotifyClient {

public chapters: ChaptersApi

public episodes: EpisodesApi

public genres: GenresApi

public markets: MarketsApi
Expand Down
100 changes: 100 additions & 0 deletions src/api/episodes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import type { EpisodeObject, GetEpisodeOptions, GetEpisodesResponse, GetSavedEpisodesOptions, PaginatedResults, SavedEpisodeObject } from '../types'
import { ApiPart } from './api.part'

export class EpisodesApi extends ApiPart {
/**
* Get Spotify catalog information for a single episode identified by its unique Spotify ID.
* @scope `user-read-playback-position`
*/
public getEpisode(id: string, opts: GetEpisodeOptions = {}): Promise<EpisodeObject> {
return this.$fetch<EpisodeObject>(`/episodes/${id}`, {
query: opts,
})
}

/**
* Get Spotify catalog information for a single episode identified by its unique Spotify ID.
* @param ids A list of the [Spotify IDs](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids).
* @scope `user-read-playback-position`
*/
public getEpisodes(ids: string[], opts: GetEpisodeOptions = {}): Promise<GetEpisodesResponse> {
return this.$fetch<GetEpisodesResponse>('/episodes', {
query: {
ids: ids.join(','),
...opts,
},
})
}

/**
* Get a list of the episodes saved in the current Spotify user's library.
*
* This API endpoint is in **beta** and could change without warning.
* Please share any feedback that you have, or issues that you discover, in our
* [developer community forum](https://community.spotify.com/t5/Spotify-for-Developers/bd-p/Spotify_Developer).
* @beta
* @scope `user-library-read`
* @scope `user-read-playback-position`
*/
public getSavedEpisodes(opts: GetSavedEpisodesOptions = {}): Promise<PaginatedResults<SavedEpisodeObject>> {
return this.$fetch<PaginatedResults<SavedEpisodeObject>>('/me/episodes', {
query: opts,
})
}

/**
* Save one or more episodes to the current user's library.
*
* This API endpoint is in **beta** and could change without warning. Please share any feedback that you have, or issues that you discover, in our
* [developer community forum](https://community.spotify.com/t5/Spotify-for-Developers/bd-p/Spotify_Developer).
* @param ids A list of the [Spotify IDs](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids).
* @beta
* @max `50` IDs.
* @scope `user-library-modify`
*/
public async saveEpisodes(ids: string[]): Promise<void> {
await this.$fetch<void>('/me/episodes', {
method: 'PUT',
query: {
ids: ids.join(','),
},
})
}

/**
* Remove one or more audiobooks to the current Spotify user's library.
*
* This API endpoint is in **beta** and could change without warning. Please share any feedback that you have, or issues that you discover, in our
* [developer community forum](https://community.spotify.com/t5/Spotify-for-Developers/bd-p/Spotify_Developer).
* @param ids A list of the [Spotify IDs](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids).
* @beta
* @max `50` IDs.
* @scope `user-library-modify`
*/
public async removeEpisodes(ids: string[]): Promise<void> {
await this.$fetch<void>('/me/episodes', {
method: 'DELETE',
query: {
ids: ids.join(','),
},
})
}

/**
* Check if one or more audiobooks are already saved in the current Spotify user's library.
*
* This API endpoint is in **beta** and could change without warning. Please share any feedback that you have, or issues that you discover, in our
* [developer community forum](https://community.spotify.com/t5/Spotify-for-Developers/bd-p/Spotify_Developer).
* @param ids A list of the [Spotify IDs](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids).
* @beta
* @max `50` IDs.
* @scope `user-library-read`
*/
public checkUserSavedEpisodes(ids: string[]): Promise<boolean[]> {
return this.$fetch<boolean[]>('/me/episodes/contains', {
query: {
ids: ids.join(','),
},
})
}
}
1 change: 1 addition & 0 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export * from './artists'
export * from './audiobooks'
export * from './categories'
export * from './chapters'
export * from './episodes'
export * from './genres'
export * from './markets'
export * from './player'
Expand Down
2 changes: 1 addition & 1 deletion src/types/audiobook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export interface AudiobookObject {
id: string

/**
* he cover art for the audiobook in various sizes, widest first.
* The cover art for the audiobook in various sizes, widest first.
*/
images: ImageObject[]

Expand Down
152 changes: 148 additions & 4 deletions src/types/episode.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,148 @@
/**
* @todo
*/
export interface EpisodeObject {}
import type { ExternalUrlObject, ImageObject, Market, PaginationQueryOptions } from './common'
import type { SimplifiedShowObject } from '.'

export interface GetEpisodeOptions {
/**
* 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
}

export interface EpisodeObject {
/**
* A URL to a 30 second preview (MP3 format) of the episode. `null` if not available.
*/
audio_preview_url: string | null

/**
* A description of the episode. HTML tags are stripped away from this field, use `html_description` field in case HTML tags are needed.
*/
description: string

/**
* A description of the episode. This field may contain HTML tags.
*/
html_description: string

/**
* Whether or not the episode has explicit content (`true` = yes it does; `false` = no it does not OR unknown).
*/
explicit: boolean

/**
* External URLs for this episode.
*/
external_urls: ExternalUrlObject

/**
* A link to the Web API endpoint providing full details of the episode.
*/
href: string

/**
* The [Spotify ID](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids) for the episode.
*/
id: string

/**
* The cover art for the episode in various sizes, widest first.
*/
images: ImageObject[]

/**
* `true` if the episode is hosted outside of Spotify's CDN.
*/
is_externally_hosted: boolean

/**
* `true` if the episode is playable in the given market. Otherwise `false`.
*/
is_playable: boolean

/**
* A list of the languages used in the audiobook, identified by their [ISO 639](https://en.wikipedia.org/wiki/ISO_639) code.
*/
languages: string[]

/**
* The language used in the episode, identified by a [ISO 639](https://en.wikipedia.org/wiki/ISO_639) code. This field is deprecated and might be removed in the future.
* Please use the languages field instead.
* @deprecated
*/
language: string

/**
* The name of the episode
*/
name: string

/**
* The date the episode was first released, for example `"1981-12-15"`. Depending on the precision, it might be shown as `"1981"` or `"1981-12"`.
*/
release_date: string

/**
* The precision with which `release_date` value is known.
*/
release_date_precision: 'year' | 'month' | 'day'

/**
* The user's most recent position in the episode. Set if the supplied access token is a user token and has the scope 'user-read-playback-position'.
*/
resume_point?: {
/**
* Whether or not the episode has been fully played by the user.
*/
fully_played: boolean

/**
* The user's most recent position in the episode in milliseconds.
*/
resume_position_ms: number
}

/**
* The object type.
*/
type: 'episode'

/**
* The [Spotify URI](https://developer.spotify.com/documentation/web-api/concepts/spotify-uris-ids) for the episode.
*/
uri: string

/**
* Included in the response when a content restriction is applied.
*/
restrictions?: {
/**
* The reason for the restriction. Supported values:
* - `market` - The content item is not available in the given market.
* - `product` - The content item is not available for the user's subscription type.
* - `explicit` - The content item is explicit and the user's account is set to not play explicit content.
*
* Additional reasons may be added in the future.
*
* **Note:** If you use this field, make sure that your application safely handles unknown values.
*/
reason: string
}

show: SimplifiedShowObject
}

export interface GetEpisodesResponse {
episodes: EpisodeObject[]
}

export interface GetSavedEpisodesOptions extends PaginationQueryOptions, GetEpisodeOptions {}

export interface SavedEpisodeObject {
/**
* The date and time the episode was saved. Timestamps are returned in ISO 8601 format as Coordinated Universal Time (UTC) with a zero offset: `YYYY-MM-DDTHH:MM:SSZ`.
*/
added_at: string

episode: EpisodeObject
}
1 change: 1 addition & 0 deletions src/types/show.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export interface SimplifiedShowObject {}

0 comments on commit 1f03119

Please sign in to comment.