diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 466df71..2be9c43 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.1.0" + ".": "0.2.0" } diff --git a/.stats.yml b/.stats.yml index 753d80d..565dbaf 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 89 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/stainless-commons%2Fspotify-139a4fc2ce0b9db4ceab46e2f76e0700a847f4e65d155f6aa7829d9753a30daf.yml -openapi_spec_hash: e96ace8fb2e27de2e776bd575bcf93a1 -config_hash: f9595b42469865c2e89f2922b389ff04 +configured_endpoints: 97 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/stainless-commons%2Fspotify-7ac9fe2ee73e38b2892f0393435f2d3a275d04b1d0728708382dd752da1d44de.yml +openapi_spec_hash: 6be3d4faa079ee82335208bec39c917a +config_hash: 656921a0de616cc4f5d5c0de5c5a64e7 diff --git a/CHANGELOG.md b/CHANGELOG.md index 717c20c..7e065a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 0.2.0 (2026-02-17) + +Full Changelog: [v0.1.0...v0.2.0](https://github.com/stainless-commons/spotify-typescript/compare/v0.1.0...v0.2.0) + +### Features + +* **api:** manual updates ([186fb31](https://github.com/stainless-commons/spotify-typescript/commit/186fb31ff5953da67c9bdd793dc854bc90990b01)) +* **api:** manual updates ([a147d29](https://github.com/stainless-commons/spotify-typescript/commit/a147d29e80f471cf69736dbc95c18665f1e6fc58)) +* **api:** manual updates ([cef5db7](https://github.com/stainless-commons/spotify-typescript/commit/cef5db7f206aad549423261e53e9f5681d88ce54)) + ## 0.1.0 (2026-02-16) Full Changelog: [v0.0.1...v0.1.0](https://github.com/stainless-commons/spotify-typescript/compare/v0.0.1...v0.1.0) diff --git a/README.md b/README.md index 4ecc698..c5b0b43 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This library provides convenient access to the Spotify REST API from server-side TypeScript or JavaScript. -The REST API documentation can be found on [spotify.cjav.dev](https://spotify.cjav.dev). The full API of this library can be found in [api.md](api.md). +The REST API documentation can be found on [stainless.com](https://stainless.com). The full API of this library can be found in [api.md](api.md). It is generated with [Stainless](https://www.stainless.com/). @@ -25,9 +25,7 @@ The full API of this library can be found in [api.md](api.md). ```js import Spotify from '@stainless-commons/spotify'; -const client = new Spotify({ - accessToken: process.env['SPOTIFY_ACCESS_TOKEN'], // This is the default and can be omitted -}); +const client = new Spotify(); const album = await client.albums.retrieve('4aawyAB9vmqN3uQ7FjRGTy'); @@ -42,9 +40,7 @@ This library includes TypeScript definitions for all request params and response ```ts import Spotify from '@stainless-commons/spotify'; -const client = new Spotify({ - accessToken: process.env['SPOTIFY_ACCESS_TOKEN'], // This is the default and can be omitted -}); +const client = new Spotify(); const album: Spotify.AlbumRetrieveResponse = await client.albums.retrieve('4aawyAB9vmqN3uQ7FjRGTy'); ``` diff --git a/SECURITY.md b/SECURITY.md index eef4b24..7e99a73 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -20,7 +20,7 @@ or products provided by Spotify, please follow the respective company's security ### Spotify Terms and Policies -Please contact wave@cjav.dev for any questions or concerns regarding the security of our services. +Please contact commons@stainless.com for any questions or concerns regarding the security of our services. --- diff --git a/api.md b/api.md index af023b5..968d90f 100644 --- a/api.md +++ b/api.md @@ -123,8 +123,13 @@ Methods: ## Playlists +Types: + +- PlaylistCreateResponse + Methods: +- client.me.playlists.create({ ...params }) -> PlaylistCreateResponse - client.me.playlists.list({ ...params }) -> SimplifiedPlaylistObjectsCursorURLPage ## Top @@ -242,6 +247,18 @@ Methods: - client.me.player.queue.add({ ...params }) -> void - client.me.player.queue.get() -> QueueGetResponse +## Library + +Types: + +- LibraryCheckSavedItemsResponse + +Methods: + +- client.me.library.checkSavedItems({ ...params }) -> LibraryCheckSavedItemsResponse +- client.me.library.removeItems({ ...params }) -> void +- client.me.library.saveItems({ ...params }) -> void + # Chapters Types: @@ -324,6 +341,21 @@ Methods: - client.playlists.images.update(playlistID, body) -> Response - client.playlists.images.list(playlistID) -> ImageListResponse +## Items + +Types: + +- ItemUpdateResponse +- ItemAddResponse +- ItemRemoveResponse + +Methods: + +- client.playlists.items.update(playlistID, { ...params }) -> ItemUpdateResponse +- client.playlists.items.list(playlistID, { ...params }) -> PlaylistTrackObjectsCursorURLPage +- client.playlists.items.add(playlistID, { ...params }) -> ItemAddResponse +- client.playlists.items.remove(playlistID, { ...params }) -> ItemRemoveResponse + # Users Types: diff --git a/package.json b/package.json index 4314005..1a794d6 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "@stainless-commons/spotify", - "version": "0.1.0", + "version": "0.2.0", "description": "The official TypeScript library for the Spotify API", - "author": "Spotify ", + "author": "Spotify ", "types": "dist/index.d.ts", "main": "dist/index.js", "type": "commonjs", diff --git a/src/client.ts b/src/client.ts index b948ef8..39df3b9 100644 --- a/src/client.ts +++ b/src/client.ts @@ -108,6 +108,7 @@ import { UserRetrieveProfileResponse, Users } from './resources/users/users'; import { type Fetch } from './internal/builtin-types'; import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers'; import { FinalRequestOptions, RequestOptions } from './internal/request-options'; +import { toBase64 } from './internal/utils/base64'; import { readEnv } from './internal/utils/env'; import { type LogLevel, @@ -120,9 +121,14 @@ import { isEmptyObj } from './internal/utils/values'; export interface ClientOptions { /** - * Defaults to process.env['SPOTIFY_ACCESS_TOKEN']. + * Defaults to process.env['SPOTIFY_CLIENT_ID']. */ - accessToken?: string | undefined; + clientID?: string | null | undefined; + + /** + * Defaults to process.env['SPOTIFY_CLIENT_SECRET']. + */ + clientSecret?: string | null | undefined; /** * Override the default base URL for the API, e.g., "https://api.example.com/v2/" @@ -197,7 +203,8 @@ export interface ClientOptions { * API Client for interfacing with the Spotify API. */ export class Spotify { - accessToken: string; + clientID: string | null; + clientSecret: string | null; baseURL: string; maxRetries: number; @@ -214,7 +221,8 @@ export class Spotify { /** * API Client for interfacing with the Spotify API. * - * @param {string | undefined} [opts.accessToken=process.env['SPOTIFY_ACCESS_TOKEN'] ?? undefined] + * @param {string | null | undefined} [opts.clientID=process.env['SPOTIFY_CLIENT_ID'] ?? null] + * @param {string | null | undefined} [opts.clientSecret=process.env['SPOTIFY_CLIENT_SECRET'] ?? null] * @param {string} [opts.baseURL=process.env['SPOTIFY_BASE_URL'] ?? https://api.spotify.com/v1] - Override the default base URL for the API. * @param {number} [opts.timeout=1 minute] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out. * @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls. @@ -225,17 +233,13 @@ export class Spotify { */ constructor({ baseURL = readEnv('SPOTIFY_BASE_URL'), - accessToken = readEnv('SPOTIFY_ACCESS_TOKEN'), + clientID = readEnv('SPOTIFY_CLIENT_ID') ?? null, + clientSecret = readEnv('SPOTIFY_CLIENT_SECRET') ?? null, ...opts }: ClientOptions = {}) { - if (accessToken === undefined) { - throw new Errors.SpotifyError( - "The SPOTIFY_ACCESS_TOKEN environment variable is missing or empty; either provide it, or instantiate the Spotify client with an accessToken option, like new Spotify({ accessToken: 'My Access Token' }).", - ); - } - const options: ClientOptions = { - accessToken, + clientID, + clientSecret, ...opts, baseURL: baseURL || `https://api.spotify.com/v1`, }; @@ -257,7 +261,8 @@ export class Spotify { this._options = options; - this.accessToken = accessToken; + this.clientID = clientID; + this.clientSecret = clientSecret; } /** @@ -273,9 +278,11 @@ export class Spotify { logLevel: this.logLevel, fetch: this.fetch, fetchOptions: this.fetchOptions, - accessToken: this.accessToken, + clientID: this.clientID, + clientSecret: this.clientSecret, ...options, }); + client.oauth2_0AuthState = this.oauth2_0AuthState; return client; } @@ -294,8 +301,72 @@ export class Spotify { return; } + private oauth2_0AuthState: + | { + promise: Promise<{ + access_token: string; + token_type: string; + expires_in: number; + expires_at: Date; + refresh_token?: string; + }>; + clientID: string; + clientSecret: string; + } + | undefined; protected async authHeaders(opts: FinalRequestOptions): Promise { - return buildHeaders([{ Authorization: `Bearer ${this.accessToken}` }]); + if (!this.clientID || !this.clientSecret) { + return undefined; + } + + // Invalidate the cache if the token is expired + if (this.oauth2_0AuthState && +(await this.oauth2_0AuthState.promise).expires_at < Date.now()) { + this.oauth2_0AuthState = undefined; + } + + // Invalidate the cache if the relevant state has been changed + if ( + this.oauth2_0AuthState && + this.oauth2_0AuthState.clientID !== this.clientID && + this.oauth2_0AuthState.clientSecret !== this.clientSecret + ) { + this.oauth2_0AuthState = undefined; + } + + if (!this.oauth2_0AuthState) { + this.oauth2_0AuthState = { + promise: this.fetch(this.buildURL('https://accounts.spotify.com/api/token', {}), { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: `Basic ${toBase64(`${this.clientID}:${this.clientSecret}`)}`, + }, + body: 'grant_type=client_credentials', + }).then(async (res) => { + if (!res.ok) { + const errText = await res.text().catch(() => ''); + const errJSON = errText ? safeJSON(errText) : undefined; + const errMessage = errJSON ? undefined : errText; + throw this.makeStatusError(res.status, errJSON, errMessage, res.headers); + } + const json = (await res.json()) as { + access_token: string; + token_type: string; + expires_in: number; + refresh_token?: string; + }; + const now = new Date(); + now.setSeconds(now.getSeconds() + json.expires_in); + return { ...json, expires_at: now }; + }), + clientID: this.clientID, + clientSecret: this.clientSecret, + }; + } + + const token = await this.oauth2_0AuthState.promise; + + return buildHeaders([{ Authorization: `Bearer ${token.access_token}` }]); } protected stringifyQuery(query: Record): string { @@ -622,6 +693,13 @@ export class Spotify { if (shouldRetryHeader === 'true') return true; if (shouldRetryHeader === 'false') return false; + // Retry if the token has expired + const oauth2_0Auth = await this.oauth2_0AuthState?.promise; + if (response.status === 401 && oauth2_0Auth && +oauth2_0Auth.expires_at - Date.now() < 10 * 1000) { + this.oauth2_0AuthState = undefined; + return true; + } + // Retry on request timeouts. if (response.status === 408) return true; diff --git a/src/resources/albums.ts b/src/resources/albums.ts index 9499eec..c46757e 100644 --- a/src/resources/albums.ts +++ b/src/resources/albums.ts @@ -23,6 +23,8 @@ export class Albums extends APIResource { /** * Get Spotify catalog information for multiple albums identified by their Spotify * IDs. + * + * @deprecated */ bulkRetrieve( query: AlbumBulkRetrieveParams, @@ -60,7 +62,7 @@ export interface AlbumRetrieveResponse { album_type: 'album' | 'single' | 'compilation'; /** - * The markets in which the album is available: + * @deprecated The markets in which the album is available: * [ISO 3166-1 alpha-2 country codes](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). * _**NOTE**: an album is considered available in a market when at least 1 of its * tracks is available in that market._ @@ -126,7 +128,7 @@ export interface AlbumRetrieveResponse { copyrights?: Array; /** - * Known external IDs for the album. + * @deprecated Known external IDs for the album. */ external_ids?: Shared.ExternalIDObject; @@ -136,13 +138,13 @@ export interface AlbumRetrieveResponse { genres?: Array; /** - * The label associated with the album. + * @deprecated The label associated with the album. */ label?: string; /** - * The popularity of the album. The value will be between 0 and 100, with 100 being - * the most popular. + * @deprecated The popularity of the album. The value will be between 0 and 100, + * with 100 being the most popular. */ popularity?: number; @@ -232,7 +234,7 @@ export namespace AlbumBulkRetrieveResponse { album_type: 'album' | 'single' | 'compilation'; /** - * The markets in which the album is available: + * @deprecated The markets in which the album is available: * [ISO 3166-1 alpha-2 country codes](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). * _**NOTE**: an album is considered available in a market when at least 1 of its * tracks is available in that market._ @@ -298,7 +300,7 @@ export namespace AlbumBulkRetrieveResponse { copyrights?: Array; /** - * Known external IDs for the album. + * @deprecated Known external IDs for the album. */ external_ids?: Shared.ExternalIDObject; @@ -308,13 +310,13 @@ export namespace AlbumBulkRetrieveResponse { genres?: Array; /** - * The label associated with the album. + * @deprecated The label associated with the album. */ label?: string; /** - * The popularity of the album. The value will be between 0 and 100, with 100 being - * the most popular. + * @deprecated The popularity of the album. The value will be between 0 and 100, + * with 100 being the most popular. */ popularity?: number; diff --git a/src/resources/artists.ts b/src/resources/artists.ts index 1f8253b..7ce1a58 100644 --- a/src/resources/artists.ts +++ b/src/resources/artists.ts @@ -18,6 +18,8 @@ export class Artists extends APIResource { /** * Get Spotify catalog information for several artists based on their Spotify IDs. + * + * @deprecated */ bulkRetrieve( query: ArtistBulkRetrieveParams, @@ -52,6 +54,8 @@ export class Artists extends APIResource { /** * Get Spotify catalog information about an artist's top tracks by country. + * + * @deprecated */ topTracks( id: string, @@ -76,7 +80,8 @@ export interface ArtistListAlbumsResponse { id: string; /** - * This field describes the relationship between the artist and the album. + * @deprecated This field describes the relationship between the artist and the + * album. */ album_group: 'album' | 'single' | 'compilation' | 'appears_on'; @@ -92,7 +97,7 @@ export interface ArtistListAlbumsResponse { artists: Array; /** - * The markets in which the album is available: + * @deprecated The markets in which the album is available: * [ISO 3166-1 alpha-2 country codes](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). * _**NOTE**: an album is considered available in a market when at least 1 of its * tracks is available in that market._ @@ -188,7 +193,7 @@ export interface ArtistListAlbumsParams { include_groups?: string; /** - * The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + * The maximum number of items to return. Default: 5. Minimum: 1. Maximum: 10. */ limit?: number; diff --git a/src/resources/audiobooks.ts b/src/resources/audiobooks.ts index 0884e5e..da5ea79 100644 --- a/src/resources/audiobooks.ts +++ b/src/resources/audiobooks.ts @@ -25,6 +25,8 @@ export class Audiobooks extends APIResource { * Get Spotify catalog information for several audiobooks identified by their * Spotify IDs. Audiobooks are only available within the US, UK, Canada, Ireland, * New Zealand and Australia markets. + * + * @deprecated */ bulkRetrieve( query: AudiobookBulkRetrieveParams, @@ -146,7 +148,8 @@ export interface SimplifiedChapterObject { uri: string; /** - * A list of the countries in which the chapter can be played, identified by their + * @deprecated A list of the countries in which the chapter can be played, + * identified by their * [ISO 3166-1 alpha-2](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code. */ available_markets?: Array; diff --git a/src/resources/browse/browse.ts b/src/resources/browse/browse.ts index 70ca55a..ca52c06 100644 --- a/src/resources/browse/browse.ts +++ b/src/resources/browse/browse.ts @@ -35,6 +35,8 @@ export class Browse extends APIResource { /** * Get a list of new album releases featured in Spotify (shown, for example, on a * Spotify player’s “Browse” tab). + * + * @deprecated */ getNewReleases( query: BrowseGetNewReleasesParams | null | undefined = {}, @@ -130,7 +132,7 @@ export namespace BrowseGetNewReleasesResponse { artists: Array; /** - * The markets in which the album is available: + * @deprecated The markets in which the album is available: * [ISO 3166-1 alpha-2 country codes](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). * _**NOTE**: an album is considered available in a market when at least 1 of its * tracks is available in that market._ diff --git a/src/resources/browse/categories.ts b/src/resources/browse/categories.ts index 05a5d9d..4fde45e 100644 --- a/src/resources/browse/categories.ts +++ b/src/resources/browse/categories.ts @@ -11,6 +11,8 @@ export class Categories extends APIResource { /** * Get a single category used to tag items in Spotify (on, for example, the Spotify * player’s “Browse” tab). + * + * @deprecated */ retrieve( categoryID: string, @@ -23,6 +25,8 @@ export class Categories extends APIResource { /** * Get a list of categories used to tag items in Spotify (on, for example, the * Spotify player’s “Browse” tab). + * + * @deprecated */ list( query: CategoryListParams | null | undefined = {}, diff --git a/src/resources/chapters.ts b/src/resources/chapters.ts index d34d139..35d064f 100644 --- a/src/resources/chapters.ts +++ b/src/resources/chapters.ts @@ -24,6 +24,8 @@ export class Chapters extends APIResource { * Get Spotify catalog information for several audiobook chapters identified by * their Spotify IDs. Chapters are only available within the US, UK, Canada, * Ireland, New Zealand and Australia markets. + * + * @deprecated */ bulkRetrieve( query: ChapterBulkRetrieveParams, @@ -132,7 +134,8 @@ export interface ChapterRetrieveResponse { uri: string; /** - * A list of the countries in which the chapter can be played, identified by their + * @deprecated A list of the countries in which the chapter can be played, + * identified by their * [ISO 3166-1 alpha-2](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code. */ available_markets?: Array; @@ -262,7 +265,8 @@ export namespace ChapterBulkRetrieveResponse { uri: string; /** - * A list of the countries in which the chapter can be played, identified by their + * @deprecated A list of the countries in which the chapter can be played, + * identified by their * [ISO 3166-1 alpha-2](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code. */ available_markets?: Array; diff --git a/src/resources/episodes.ts b/src/resources/episodes.ts index 4b52000..3a25a99 100644 --- a/src/resources/episodes.ts +++ b/src/resources/episodes.ts @@ -21,6 +21,8 @@ export class Episodes extends APIResource { /** * Get Spotify catalog information for several episodes based on their Spotify IDs. + * + * @deprecated */ bulkRetrieve( query: EpisodeBulkRetrieveParams, diff --git a/src/resources/markets.ts b/src/resources/markets.ts index 15a44e5..c24cf7a 100644 --- a/src/resources/markets.ts +++ b/src/resources/markets.ts @@ -7,6 +7,8 @@ import { RequestOptions } from '../internal/request-options'; export class Markets extends APIResource { /** * Get the list of markets where Spotify is available. + * + * @deprecated */ list(options?: RequestOptions): APIPromise { return this._client.get('/markets', options); diff --git a/src/resources/me/albums.ts b/src/resources/me/albums.ts index a426ebc..394bdd0 100644 --- a/src/resources/me/albums.ts +++ b/src/resources/me/albums.ts @@ -31,12 +31,11 @@ export class Albums extends APIResource { * Check if one or more albums is already saved in the current Spotify user's 'Your * Music' library. * - * @example - * ```ts - * const response = await client.me.albums.check({ - * ids: '382ObEPsp2rxGrnsizN5TX,1A2GTWGtFfWp7KSQTwWOyo,2noRn2Aes5aoNVsU6iWThc', - * }); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Check User's Saved Items](/documentation/web-api/reference/check-library-contains) + * instead. + * + * @deprecated */ check(query: AlbumCheckParams, options?: RequestOptions): APIPromise { return this._client.get('/me/albums/contains', { query, ...options }); @@ -45,10 +44,11 @@ export class Albums extends APIResource { /** * Remove one or more albums from the current user's 'Your Music' library. * - * @example - * ```ts - * await client.me.albums.remove(); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Remove Items from Library](/documentation/web-api/reference/remove-library-items) + * instead. + * + * @deprecated */ remove(body: AlbumRemoveParams | null | undefined = {}, options?: RequestOptions): APIPromise { return this._client.delete('/me/albums', { @@ -61,10 +61,11 @@ export class Albums extends APIResource { /** * Save one or more albums to the current user's 'Your Music' library. * - * @example - * ```ts - * await client.me.albums.save(); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Save Items to Library](/documentation/web-api/reference/save-library-items) + * instead. + * + * @deprecated */ save(body: AlbumSaveParams | null | undefined = {}, options?: RequestOptions): APIPromise { return this._client.put('/me/albums', { @@ -119,7 +120,7 @@ export namespace AlbumListResponse { album_type: 'album' | 'single' | 'compilation'; /** - * The markets in which the album is available: + * @deprecated The markets in which the album is available: * [ISO 3166-1 alpha-2 country codes](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). * _**NOTE**: an album is considered available in a market when at least 1 of its * tracks is available in that market._ @@ -185,7 +186,7 @@ export namespace AlbumListResponse { copyrights?: Array; /** - * Known external IDs for the album. + * @deprecated Known external IDs for the album. */ external_ids?: Shared.ExternalIDObject; @@ -195,13 +196,13 @@ export namespace AlbumListResponse { genres?: Array; /** - * The label associated with the album. + * @deprecated The label associated with the album. */ label?: string; /** - * The popularity of the album. The value will be between 0 and 100, with 100 being - * the most popular. + * @deprecated The popularity of the album. The value will be between 0 and 100, + * with 100 being the most popular. */ popularity?: number; diff --git a/src/resources/me/audiobooks.ts b/src/resources/me/audiobooks.ts index 7f8e2ff..b4cba22 100644 --- a/src/resources/me/audiobooks.ts +++ b/src/resources/me/audiobooks.ts @@ -35,12 +35,11 @@ export class Audiobooks extends APIResource { * Check if one or more audiobooks are already saved in the current Spotify user's * library. * - * @example - * ```ts - * const response = await client.me.audiobooks.check({ - * ids: '18yVqkdbdRvS24c0Ilj2ci,1HGw3J3NxZO1TP1BTtVhpZ,7iHfbu1YPACw6oZPAFJtqe', - * }); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Check User's Saved Items](/documentation/web-api/reference/check-library-contains) + * instead. + * + * @deprecated */ check(query: AudiobookCheckParams, options?: RequestOptions): APIPromise { return this._client.get('/me/audiobooks/contains', { query, ...options }); @@ -49,12 +48,11 @@ export class Audiobooks extends APIResource { /** * Remove one or more audiobooks from the Spotify user's library. * - * @example - * ```ts - * await client.me.audiobooks.remove({ - * ids: '18yVqkdbdRvS24c0Ilj2ci,1HGw3J3NxZO1TP1BTtVhpZ,7iHfbu1YPACw6oZPAFJtqe', - * }); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Remove Items from Library](/documentation/web-api/reference/remove-library-items) + * instead. + * + * @deprecated */ remove(params: AudiobookRemoveParams, options?: RequestOptions): APIPromise { const { ids } = params; @@ -68,12 +66,11 @@ export class Audiobooks extends APIResource { /** * Save one or more audiobooks to the current Spotify user's library. * - * @example - * ```ts - * await client.me.audiobooks.save({ - * ids: '18yVqkdbdRvS24c0Ilj2ci,1HGw3J3NxZO1TP1BTtVhpZ,7iHfbu1YPACw6oZPAFJtqe', - * }); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Save Items to Library](/documentation/web-api/reference/save-library-items) + * instead. + * + * @deprecated */ save(params: AudiobookSaveParams, options?: RequestOptions): APIPromise { const { ids } = params; diff --git a/src/resources/me/episodes.ts b/src/resources/me/episodes.ts index 288b3c4..57f16bf 100644 --- a/src/resources/me/episodes.ts +++ b/src/resources/me/episodes.ts @@ -9,10 +9,7 @@ import { RequestOptions } from '../../internal/request-options'; export class Episodes extends APIResource { /** - * 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). + * Get a list of the episodes saved in the current Spotify user's library. * * @example * ```ts @@ -31,32 +28,26 @@ export class Episodes extends APIResource { /** * Check if one or more episodes is already saved in the current Spotify user's - * 'Your Episodes' 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).. + * 'Your Episodes' library. * - * @example - * ```ts - * const response = await client.me.episodes.check({ - * ids: '77o6BIVlYM3msb4MMIL1jH,0Q86acNRm6V9GYx55SXKwf', - * }); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Check User's Saved Items](/documentation/web-api/reference/check-library-contains) + * instead. + * + * @deprecated */ check(query: EpisodeCheckParams, options?: RequestOptions): APIPromise { return this._client.get('/me/episodes/contains', { query, ...options }); } /** - * Remove one or more episodes from 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). + * Remove one or more episodes from the current user's library. * - * @example - * ```ts - * await client.me.episodes.remove(); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Remove Items from Library](/documentation/web-api/reference/remove-library-items) + * instead. + * + * @deprecated */ remove(body: EpisodeRemoveParams | null | undefined = {}, options?: RequestOptions): APIPromise { return this._client.delete('/me/episodes', { @@ -67,15 +58,13 @@ export class Episodes extends APIResource { } /** - * 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). + * Save one or more episodes to the current user's library. * - * @example - * ```ts - * await client.me.episodes.save({ ids: ['string'] }); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Save Items to Library](/documentation/web-api/reference/save-library-items) + * instead. + * + * @deprecated */ save(body: EpisodeSaveParams, options?: RequestOptions): APIPromise { return this._client.put('/me/episodes', { diff --git a/src/resources/me/following.ts b/src/resources/me/following.ts index d185681..0a4227d 100644 --- a/src/resources/me/following.ts +++ b/src/resources/me/following.ts @@ -28,13 +28,11 @@ export class Following extends APIResource { * Check to see if the current user is following one or more artists or other * Spotify users. * - * @example - * ```ts - * const response = await client.me.following.check({ - * ids: '2CIMQHirSU0MQqyYHq0eOx,57dN52uHvrHOxijzpIgu3E,1vCWHaC5f2uS3yhpwWbIA6', - * type: 'artist', - * }); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Check User's Saved Items](/documentation/web-api/reference/check-library-contains) + * instead. + * + * @deprecated */ check(query: FollowingCheckParams, options?: RequestOptions): APIPromise { return this._client.get('/me/following/contains', { query, ...options }); @@ -44,10 +42,11 @@ export class Following extends APIResource { * Add the current user as a follower of one or more artists or other Spotify * users. * - * @example - * ```ts - * await client.me.following.follow({ ids: ['string'] }); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Save Items to Library](/documentation/web-api/reference/save-library-items) + * instead. + * + * @deprecated */ follow(body: FollowingFollowParams, options?: RequestOptions): APIPromise { return this._client.put('/me/following', { @@ -61,10 +60,11 @@ export class Following extends APIResource { * Remove the current user as a follower of one or more artists or other Spotify * users. * - * @example - * ```ts - * await client.me.following.unfollow(); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Remove Items from Library](/documentation/web-api/reference/remove-library-items) + * instead. + * + * @deprecated */ unfollow( body: FollowingUnfollowParams | null | undefined = {}, diff --git a/src/resources/me/index.ts b/src/resources/me/index.ts index c187282..b5c0ec1 100644 --- a/src/resources/me/index.ts +++ b/src/resources/me/index.ts @@ -39,6 +39,13 @@ export { type FollowingFollowParams, type FollowingUnfollowParams, } from './following'; +export { + Library, + type LibraryCheckSavedItemsResponse, + type LibraryCheckSavedItemsParams, + type LibraryRemoveItemsParams, + type LibrarySaveItemsParams, +} from './library'; export { Me, type MeRetrieveResponse } from './me'; export { Player, @@ -62,7 +69,12 @@ export { type PlayerTransferParams, type PlayerListRecentlyPlayedResponsesCursorURLPage, } from './player/index'; -export { Playlists, type PlaylistListParams } from './playlists'; +export { + Playlists, + type PlaylistCreateResponse, + type PlaylistCreateParams, + type PlaylistListParams, +} from './playlists'; export { Shows, type ShowListResponse, diff --git a/src/resources/me/library.ts b/src/resources/me/library.ts new file mode 100644 index 0000000..9d7724d --- /dev/null +++ b/src/resources/me/library.ts @@ -0,0 +1,136 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { APIResource } from '../../core/resource'; +import { APIPromise } from '../../core/api-promise'; +import { buildHeaders } from '../../internal/headers'; +import { RequestOptions } from '../../internal/request-options'; + +export class Library extends APIResource { + /** + * Check if one or more items are already saved in the current user's library. + * Accepts Spotify URIs for tracks, albums, episodes, shows, audiobooks, artists, + * users, and playlists. + * + * @example + * ```ts + * const response = await client.me.library.checkSavedItems({ + * uris: 'spotify:track:7a3LWj5xSFhFRYmztS8wgK,spotify:album:4aawyAB9vmqN3uQ7FjRGTy,spotify:artist:2takcwOaAZWiXQijPHIx7B', + * }); + * ``` + */ + checkSavedItems( + query: LibraryCheckSavedItemsParams, + options?: RequestOptions, + ): APIPromise { + return this._client.get('/me/library/contains', { query, ...options }); + } + + /** + * Remove one or more items from the current user's library. Accepts Spotify URIs + * for tracks, albums, episodes, shows, audiobooks, users, and playlists. + * + * @example + * ```ts + * await client.me.library.removeItems({ + * uris: 'spotify:track:7a3LWj5xSFhFRYmztS8wgK,spotify:album:4aawyAB9vmqN3uQ7FjRGTy', + * }); + * ``` + */ + removeItems(params: LibraryRemoveItemsParams, options?: RequestOptions): APIPromise { + const { uris } = params; + return this._client.delete('/me/library', { + query: { uris }, + ...options, + headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), + }); + } + + /** + * Add one or more items to the current user's library. Accepts Spotify URIs for + * tracks, albums, episodes, shows, audiobooks, users, and playlists. + * + * @example + * ```ts + * await client.me.library.saveItems({ + * uris: 'spotify:track:7a3LWj5xSFhFRYmztS8wgK,spotify:album:4aawyAB9vmqN3uQ7FjRGTy', + * }); + * ``` + */ + saveItems(params: LibrarySaveItemsParams, options?: RequestOptions): APIPromise { + const { uris } = params; + return this._client.put('/me/library', { + query: { uris }, + ...options, + headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), + }); + } +} + +export type LibraryCheckSavedItemsResponse = Array; + +export interface LibraryCheckSavedItemsParams { + /** + * A comma-separated list of + * [Spotify URIs](/documentation/web-api/concepts/spotify-uris-ids). Maximum: 40 + * URIs. + * + * Supported URI types: + * + * - `spotify:track:{id}` + * - `spotify:album:{id}` + * - `spotify:episode:{id}` + * - `spotify:show:{id}` + * - `spotify:audiobook:{id}` + * - `spotify:artist:{id}` + * - `spotify:user:{id}` + * - `spotify:playlist:{id}` + */ + uris: string; +} + +export interface LibraryRemoveItemsParams { + /** + * A comma-separated list of + * [Spotify URIs](/documentation/web-api/concepts/spotify-uris-ids). Maximum: 40 + * URIs. + * + * Supported URI types: + * + * - `spotify:track:{id}` + * - `spotify:album:{id}` + * - `spotify:episode:{id}` + * - `spotify:show:{id}` + * - `spotify:audiobook:{id}` + * - `spotify:user:{id}` + * - `spotify:playlist:{id}` + */ + uris: string; +} + +export interface LibrarySaveItemsParams { + /** + * A comma-separated list of + * [Spotify URIs](/documentation/web-api/concepts/spotify-uris-ids). Maximum: 40 + * URIs. + * + * Supported URI types: + * + * - `spotify:track:{id}` + * - `spotify:album:{id}` + * - `spotify:episode:{id}` + * - `spotify:show:{id}` + * - `spotify:audiobook:{id}` + * - `spotify:user:{id}` + * - `spotify:playlist:{id}` + */ + uris: string; +} + +export declare namespace Library { + export { + type LibraryCheckSavedItemsResponse as LibraryCheckSavedItemsResponse, + type LibraryCheckSavedItemsParams as LibraryCheckSavedItemsParams, + type LibraryRemoveItemsParams as LibraryRemoveItemsParams, + type LibrarySaveItemsParams as LibrarySaveItemsParams, + }; +} diff --git a/src/resources/me/me.ts b/src/resources/me/me.ts index 91999a6..b721c5e 100644 --- a/src/resources/me/me.ts +++ b/src/resources/me/me.ts @@ -45,8 +45,16 @@ import { FollowingFollowParams, FollowingUnfollowParams, } from './following'; +import * as LibraryAPI from './library'; +import { + Library, + LibraryCheckSavedItemsParams, + LibraryCheckSavedItemsResponse, + LibraryRemoveItemsParams, + LibrarySaveItemsParams, +} from './library'; import * as PlaylistsAPI from './playlists'; -import { PlaylistListParams, Playlists } from './playlists'; +import { PlaylistCreateParams, PlaylistCreateResponse, PlaylistListParams, Playlists } from './playlists'; import * as ShowsAPI from './shows'; import { ShowCheckParams, @@ -107,6 +115,7 @@ export class Me extends APIResource { shows: ShowsAPI.Shows = new ShowsAPI.Shows(this._client); following: FollowingAPI.Following = new FollowingAPI.Following(this._client); player: PlayerAPI.Player = new PlayerAPI.Player(this._client); + library: LibraryAPI.Library = new LibraryAPI.Library(this._client); /** * Get detailed profile information about the current user (including the current @@ -130,7 +139,7 @@ export interface MeRetrieveResponse { id?: string; /** - * The country of the user, as set in the user's account profile. An + * @deprecated The country of the user, as set in the user's account profile. An * [ISO 3166-1 alpha-2 country code](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). * _This field is only available when the current user has granted access to the * [user-read-private](/documentation/web-api/concepts/scopes/#list-of-scopes) @@ -144,18 +153,18 @@ export interface MeRetrieveResponse { display_name?: string; /** - * The user's email address, as entered by the user when creating their account. - * _**Important!** This email address is unverified; there is no proof that it - * actually belongs to the user._ _This field is only available when the current - * user has granted access to the + * @deprecated The user's email address, as entered by the user when creating their + * account. _**Important!** This email address is unverified; there is no proof + * that it actually belongs to the user._ _This field is only available when the + * current user has granted access to the * [user-read-email](/documentation/web-api/concepts/scopes/#list-of-scopes) * scope._ */ email?: string; /** - * The user's explicit content settings. _This field is only available when the - * current user has granted access to the + * @deprecated The user's explicit content settings. _This field is only available + * when the current user has granted access to the * [user-read-private](/documentation/web-api/concepts/scopes/#list-of-scopes) * scope._ */ @@ -167,7 +176,7 @@ export interface MeRetrieveResponse { external_urls?: Shared.ExternalURLObject; /** - * Information about the followers of the user. + * @deprecated Information about the followers of the user. */ followers?: Shared.FollowersObject; @@ -182,9 +191,9 @@ export interface MeRetrieveResponse { images?: Array; /** - * The user's Spotify subscription level: "premium", "free", etc. (The subscription - * level "open" can be considered the same as "free".) _This field is only - * available when the current user has granted access to the + * @deprecated The user's Spotify subscription level: "premium", "free", etc. (The + * subscription level "open" can be considered the same as "free".) _This field is + * only available when the current user has granted access to the * [user-read-private](/documentation/web-api/concepts/scopes/#list-of-scopes) * scope._ */ @@ -213,8 +222,8 @@ export interface MeRetrieveResponse { export namespace MeRetrieveResponse { /** - * The user's explicit content settings. _This field is only available when the - * current user has granted access to the + * @deprecated The user's explicit content settings. _This field is only available + * when the current user has granted access to the * [user-read-private](/documentation/web-api/concepts/scopes/#list-of-scopes) * scope._ */ @@ -250,6 +259,7 @@ Me.Episodes = Episodes; Me.Shows = Shows; Me.Following = Following; Me.Player = Player; +Me.Library = Library; export declare namespace Me { export { type MeRetrieveResponse as MeRetrieveResponse }; @@ -265,7 +275,12 @@ export declare namespace Me { type AudiobookSaveParams as AudiobookSaveParams, }; - export { Playlists as Playlists, type PlaylistListParams as PlaylistListParams }; + export { + Playlists as Playlists, + type PlaylistCreateResponse as PlaylistCreateResponse, + type PlaylistCreateParams as PlaylistCreateParams, + type PlaylistListParams as PlaylistListParams, + }; export { Top as Top, @@ -349,4 +364,12 @@ export declare namespace Me { type PlayerToggleShuffleParams as PlayerToggleShuffleParams, type PlayerTransferParams as PlayerTransferParams, }; + + export { + Library as Library, + type LibraryCheckSavedItemsResponse as LibraryCheckSavedItemsResponse, + type LibraryCheckSavedItemsParams as LibraryCheckSavedItemsParams, + type LibraryRemoveItemsParams as LibraryRemoveItemsParams, + type LibrarySaveItemsParams as LibrarySaveItemsParams, + }; } diff --git a/src/resources/me/playlists.ts b/src/resources/me/playlists.ts index 5e874d2..c623c20 100644 --- a/src/resources/me/playlists.ts +++ b/src/resources/me/playlists.ts @@ -3,10 +3,28 @@ import { APIResource } from '../../core/resource'; import * as Shared from '../shared'; import { SimplifiedPlaylistObjectsCursorURLPage } from '../shared'; +import { APIPromise } from '../../core/api-promise'; import { CursorURLPage, PagePromise } from '../../core/pagination'; import { RequestOptions } from '../../internal/request-options'; export class Playlists extends APIResource { + /** + * Create a playlist for the current Spotify user. (The playlist will be empty + * until you + * [add tracks](/documentation/web-api/reference/add-tracks-to-playlist).) Each + * user is generally limited to a maximum of 11000 playlists. + * + * @example + * ```ts + * const playlist = await client.me.playlists.create({ + * name: 'New Playlist', + * }); + * ``` + */ + create(body: PlaylistCreateParams, options?: RequestOptions): APIPromise { + return this._client.post('/me/playlists', { body, ...options }); + } + /** * Get a list of the playlists owned or followed by the current Spotify user. * @@ -29,6 +47,236 @@ export class Playlists extends APIResource { } } +export interface PlaylistCreateResponse { + /** + * The [Spotify ID](/documentation/web-api/concepts/spotify-uris-ids) for the + * playlist. + */ + id?: string; + + /** + * `true` if the owner allows other users to modify the playlist. + */ + collaborative?: boolean; + + /** + * The playlist description. _Only returned for modified, verified playlists, + * otherwise_ `null`. + */ + description?: string | null; + + /** + * Known external URLs for this playlist. + */ + external_urls?: Shared.ExternalURLObject; + + /** + * Information about the followers of the playlist. + */ + followers?: Shared.FollowersObject; + + /** + * A link to the Web API endpoint providing full details of the playlist. + */ + href?: string; + + /** + * Images for the playlist. The array may be empty or contain up to three images. + * The images are returned by size in descending order. See + * [Working with Playlists](/documentation/web-api/concepts/playlists). _**Note**: + * If returned, the source URL for the image (`url`) is temporary and will expire + * in less than a day._ + */ + images?: Array; + + /** + * The items of the playlist. _**Note**: This field is only available for playlists + * owned by the current user or playlists the user is a collaborator of._ + */ + items?: PlaylistCreateResponse.Items; + + /** + * The name of the playlist. + */ + name?: string; + + /** + * The user who owns the playlist + */ + owner?: PlaylistCreateResponse.Owner; + + /** + * The playlist's public/private status (if it should be added to the user's + * profile or not): `true` the playlist will be public, `false` the playlist will + * be private, `null` the playlist status is not relevant. For more about + * public/private status, see + * [Working with Playlists](/documentation/web-api/concepts/playlists) + */ + published?: boolean; + + /** + * The version identifier for the current playlist. Can be supplied in other + * requests to target a specific playlist version + */ + snapshot_id?: string; + + /** + * @deprecated **Deprecated:** Use `items` instead. The tracks of the playlist. + */ + tracks?: PlaylistCreateResponse.Tracks; + + /** + * The object type: "playlist" + */ + type?: string; + + /** + * The [Spotify URI](/documentation/web-api/concepts/spotify-uris-ids) for the + * playlist. + */ + uri?: string; +} + +export namespace PlaylistCreateResponse { + /** + * The items of the playlist. _**Note**: This field is only available for playlists + * owned by the current user or playlists the user is a collaborator of._ + */ + export interface Items { + /** + * A link to the Web API endpoint returning the full result of the request + */ + href: string; + + /** + * The maximum number of items in the response (as set in the query or by default). + */ + limit: number; + + /** + * URL to the next page of items. ( `null` if none) + */ + next: string | null; + + /** + * The offset of the items returned (as set in the query or by default) + */ + offset: number; + + /** + * URL to the previous page of items. ( `null` if none) + */ + previous: string | null; + + /** + * The total number of items available to return. + */ + total: number; + + items?: Array; + + /** + * The playlist's public/private status (if it should be added to the user's + * profile or not): `true` the playlist will be public, `false` the playlist will + * be private, `null` the playlist status is not relevant. For more about + * public/private status, see + * [Working with Playlists](/documentation/web-api/concepts/playlists) + */ + published?: boolean; + } + + /** + * The user who owns the playlist + */ + export interface Owner extends Shared.PlaylistUserObject { + /** + * The name displayed on the user's profile. `null` if not available. + */ + display_name?: string | null; + } + + /** + * @deprecated **Deprecated:** Use `items` instead. The tracks of the playlist. + */ + export interface Tracks { + /** + * A link to the Web API endpoint returning the full result of the request + */ + href: string; + + /** + * The maximum number of items in the response (as set in the query or by default). + */ + limit: number; + + /** + * URL to the next page of items. ( `null` if none) + */ + next: string | null; + + /** + * The offset of the items returned (as set in the query or by default) + */ + offset: number; + + /** + * URL to the previous page of items. ( `null` if none) + */ + previous: string | null; + + /** + * The total number of items available to return. + */ + total: number; + + items?: Array; + + /** + * The playlist's public/private status (if it should be added to the user's + * profile or not): `true` the playlist will be public, `false` the playlist will + * be private, `null` the playlist status is not relevant. For more about + * public/private status, see + * [Working with Playlists](/documentation/web-api/concepts/playlists) + */ + published?: boolean; + } +} + +export interface PlaylistCreateParams { + /** + * The name for the new playlist, for example `"Your Coolest Playlist"`. This name + * does not need to be unique; a user may have several playlists with the same + * name. + */ + name: string; + + /** + * Defaults to `false`. If `true` the playlist will be collaborative. _**Note**: to + * create a collaborative playlist you must also set `public` to `false`. To create + * collaborative playlists you must have granted `playlist-modify-private` and + * `playlist-modify-public` + * [scopes](/documentation/web-api/concepts/scopes/#list-of-scopes)._ + */ + collaborative?: boolean; + + /** + * value for playlist description as displayed in Spotify Clients and in the Web + * API. + */ + description?: string; + + /** + * The playlist's public/private status (if it should be added to the user's + * profile or not): `true` the playlist will be public, `false` the playlist will + * be private, `null` the playlist status is not relevant. For more about + * public/private status, see + * [Working with Playlists](/documentation/web-api/concepts/playlists) + */ + published?: boolean; + + [k: string]: unknown; +} + export interface PlaylistListParams { /** * The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. @@ -43,7 +291,11 @@ export interface PlaylistListParams { } export declare namespace Playlists { - export { type PlaylistListParams as PlaylistListParams }; + export { + type PlaylistCreateResponse as PlaylistCreateResponse, + type PlaylistCreateParams as PlaylistCreateParams, + type PlaylistListParams as PlaylistListParams, + }; } export { type SimplifiedPlaylistObjectsCursorURLPage }; diff --git a/src/resources/me/shows.ts b/src/resources/me/shows.ts index 7ac05e8..6b33ab2 100644 --- a/src/resources/me/shows.ts +++ b/src/resources/me/shows.ts @@ -31,12 +31,11 @@ export class Shows extends APIResource { * Check if one or more shows is already saved in the current Spotify user's * library. * - * @example - * ```ts - * const response = await client.me.shows.check({ - * ids: '5CfCWKI5pZ28U0uOzXkDHe,5as3aKmN2k11yfDDDSrvaZ', - * }); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Check User's Saved Items](/documentation/web-api/reference/check-library-contains) + * instead. + * + * @deprecated */ check(query: ShowCheckParams, options?: RequestOptions): APIPromise { return this._client.get('/me/shows/contains', { query, ...options }); @@ -45,10 +44,11 @@ export class Shows extends APIResource { /** * Delete one or more shows from current Spotify user's library. * - * @example - * ```ts - * await client.me.shows.remove(); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Remove Items from Library](/documentation/web-api/reference/remove-library-items) + * instead. + * + * @deprecated */ remove(body: ShowRemoveParams | null | undefined = {}, options?: RequestOptions): APIPromise { return this._client.delete('/me/shows', { @@ -61,10 +61,11 @@ export class Shows extends APIResource { /** * Save one or more shows to current Spotify user's library. * - * @example - * ```ts - * await client.me.shows.save(); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Save Items to Library](/documentation/web-api/reference/save-library-items) + * instead. + * + * @deprecated */ save(body: ShowSaveParams | null | undefined = {}, options?: RequestOptions): APIPromise { return this._client.put('/me/shows', { diff --git a/src/resources/me/tracks.ts b/src/resources/me/tracks.ts index 988cf29..61295eb 100644 --- a/src/resources/me/tracks.ts +++ b/src/resources/me/tracks.ts @@ -31,12 +31,11 @@ export class Tracks extends APIResource { * Check if one or more tracks is already saved in the current Spotify user's 'Your * Music' library. * - * @example - * ```ts - * const response = await client.me.tracks.check({ - * ids: '7ouMYWpwJ422jRcDASZB7P,4VqPOruhp5EdPBeR92t6lQ,2takcwOaAZWiXQijPHIx7B', - * }); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Check User's Saved Items](/documentation/web-api/reference/check-library-contains) + * instead. + * + * @deprecated */ check(query: TrackCheckParams, options?: RequestOptions): APIPromise { return this._client.get('/me/tracks/contains', { query, ...options }); @@ -45,10 +44,11 @@ export class Tracks extends APIResource { /** * Remove one or more tracks from the current user's 'Your Music' library. * - * @example - * ```ts - * await client.me.tracks.remove(); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Remove Items from Library](/documentation/web-api/reference/remove-library-items) + * instead. + * + * @deprecated */ remove(body: TrackRemoveParams | null | undefined = {}, options?: RequestOptions): APIPromise { return this._client.delete('/me/tracks', { @@ -61,10 +61,11 @@ export class Tracks extends APIResource { /** * Save one or more tracks to the current user's 'Your Music' library. * - * @example - * ```ts - * await client.me.tracks.save({ ids: ['string'] }); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Save Items to Library](/documentation/web-api/reference/save-library-items) + * instead. + * + * @deprecated */ save(body: TrackSaveParams, options?: RequestOptions): APIPromise { return this._client.put('/me/tracks', { diff --git a/src/resources/playlists/followers.ts b/src/resources/playlists/followers.ts index 80afc21..e5a8cee 100644 --- a/src/resources/playlists/followers.ts +++ b/src/resources/playlists/followers.ts @@ -10,12 +10,11 @@ export class Followers extends APIResource { /** * Check to see if the current user is following a specified playlist. * - * @example - * ```ts - * const response = await client.playlists.followers.check( - * '3cEYpjA9oz9GiPac4AsH4n', - * ); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Check User's Saved Items](/documentation/web-api/reference/check-library-contains) + * instead. + * + * @deprecated */ check( playlistID: string, @@ -28,12 +27,11 @@ export class Followers extends APIResource { /** * Add the current user as a follower of a playlist. * - * @example - * ```ts - * await client.playlists.followers.follow( - * '3cEYpjA9oz9GiPac4AsH4n', - * ); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Save Items to Library](/documentation/web-api/reference/save-library-items) + * instead. + * + * @deprecated */ follow( playlistID: string, @@ -50,12 +48,11 @@ export class Followers extends APIResource { /** * Remove the current user as a follower of a playlist. * - * @example - * ```ts - * await client.playlists.followers.unfollow( - * '3cEYpjA9oz9GiPac4AsH4n', - * ); - * ``` + * **Note:** This endpoint is deprecated. Use + * [Remove Items from Library](/documentation/web-api/reference/remove-library-items) + * instead. + * + * @deprecated */ unfollow(playlistID: string, options?: RequestOptions): APIPromise { return this._client.delete(path`/playlists/${playlistID}/followers`, { diff --git a/src/resources/playlists/index.ts b/src/resources/playlists/index.ts index 8e9b70c..5848b95 100644 --- a/src/resources/playlists/index.ts +++ b/src/resources/playlists/index.ts @@ -7,6 +7,16 @@ export { type FollowerFollowParams, } from './followers'; export { Images, type ImageListResponse } from './images'; +export { + Items, + type ItemUpdateResponse, + type ItemAddResponse, + type ItemRemoveResponse, + type ItemUpdateParams, + type ItemListParams, + type ItemAddParams, + type ItemRemoveParams, +} from './items'; export { Playlists, type PlaylistRetrieveResponse, diff --git a/src/resources/playlists/items.ts b/src/resources/playlists/items.ts new file mode 100644 index 0000000..0c545a2 --- /dev/null +++ b/src/resources/playlists/items.ts @@ -0,0 +1,338 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { APIResource } from '../../core/resource'; +import * as Shared from '../shared'; +import { PlaylistTrackObjectsCursorURLPage } from '../shared'; +import { APIPromise } from '../../core/api-promise'; +import { CursorURLPage, PagePromise } from '../../core/pagination'; +import { RequestOptions } from '../../internal/request-options'; +import { path } from '../../internal/utils/path'; + +export class Items extends APIResource { + /** + * Either reorder or replace items in a playlist depending on the request's + * parameters. To reorder items, include `range_start`, `insert_before`, + * `range_length` and `snapshot_id` in the request's body. To replace items, + * include `uris` as either a query parameter or in the request's body. Replacing + * items in a playlist will overwrite its existing items. This operation can be + * used for replacing or clearing items in a playlist.
**Note**: Replace and + * reorder are mutually exclusive operations which share the same endpoint, but + * have different parameters. These operations can't be applied together in a + * single request. + * + * @example + * ```ts + * const item = await client.playlists.items.update( + * '3cEYpjA9oz9GiPac4AsH4n', + * ); + * ``` + */ + update( + playlistID: string, + params: ItemUpdateParams | null | undefined = {}, + options?: RequestOptions, + ): APIPromise { + const { query_uris, ...body } = params ?? {}; + return this._client.put(path`/playlists/${playlistID}/items`, { + query: { uris: query_uris }, + body, + ...options, + }); + } + + /** + * Get full details of the items of a playlist owned by a Spotify user. + * + * **Note**: This endpoint is only accessible for playlists owned by the current + * user or playlists the user is a collaborator of. A `403 Forbidden` status code + * will be returned if the user is neither the owner nor a collaborator of the + * playlist. + * + * @example + * ```ts + * // Automatically fetches more pages as needed. + * for await (const playlistTrackObject of client.playlists.items.list( + * '3cEYpjA9oz9GiPac4AsH4n', + * )) { + * // ... + * } + * ``` + */ + list( + playlistID: string, + query: ItemListParams | null | undefined = {}, + options?: RequestOptions, + ): PagePromise { + return this._client.getAPIList( + path`/playlists/${playlistID}/items`, + CursorURLPage, + { query, ...options }, + ); + } + + /** + * Add one or more items to a user's playlist. + * + * @example + * ```ts + * const response = await client.playlists.items.add( + * '3cEYpjA9oz9GiPac4AsH4n', + * ); + * ``` + */ + add( + playlistID: string, + params: ItemAddParams | null | undefined = {}, + options?: RequestOptions, + ): APIPromise { + const { query_position, query_uris, ...body } = params ?? {}; + return this._client.post(path`/playlists/${playlistID}/items`, { + query: { position: query_position, uris: query_uris }, + body, + ...options, + }); + } + + /** + * Remove one or more items from a user's playlist. + * + * @example + * ```ts + * const item = await client.playlists.items.remove( + * '3cEYpjA9oz9GiPac4AsH4n', + * { items: [{}] }, + * ); + * ``` + */ + remove( + playlistID: string, + body: ItemRemoveParams, + options?: RequestOptions, + ): APIPromise { + return this._client.delete(path`/playlists/${playlistID}/items`, { body, ...options }); + } +} + +export interface ItemUpdateResponse { + snapshot_id?: string; +} + +export interface ItemAddResponse { + snapshot_id?: string; +} + +export interface ItemRemoveResponse { + snapshot_id?: string; +} + +export interface ItemUpdateParams { + /** + * Query param: A comma-separated list of + * [Spotify URIs](/documentation/web-api/concepts/spotify-uris-ids) to set, can be + * track or episode URIs. For example: + * `uris=spotify:track:4iV5W9uYEdYUVa79Axb7Rh,spotify:track:1301WleyT98MSxVHPZCA6M,spotify:episode:512ojhOuo1ktJprKbVcKyQ`
A + * maximum of 100 items can be set in one request. + */ + query_uris?: string; + + /** + * Body param: The position where the items should be inserted.
To reorder the + * items to the end of the playlist, simply set _insert_before_ to the position + * after the last item.
Examples:
To reorder the first item to the last + * position in a playlist with 10 items, set _range_start_ to 0, and + * _insert_before_ to 10.
To reorder the last item in a playlist with 10 items + * to the start of the playlist, set _range_start_ to 9, and _insert_before_ to 0. + */ + insert_before?: number; + + /** + * Body param: The playlist's public/private status (if it should be added to the + * user's profile or not): `true` the playlist will be public, `false` the playlist + * will be private, `null` the playlist status is not relevant. For more about + * public/private status, see + * [Working with Playlists](/documentation/web-api/concepts/playlists) + */ + published?: boolean; + + /** + * Body param: The amount of items to be reordered. Defaults to 1 if not + * set.
The range of items to be reordered begins from the _range_start_ + * position, and includes the _range_length_ subsequent items.
Example:
To + * move the items at index 9-10 to the start of the playlist, _range_start_ is set + * to 9, and _range_length_ is set to 2. + */ + range_length?: number; + + /** + * Body param: The position of the first item to be reordered. + */ + range_start?: number; + + /** + * Body param: The playlist's snapshot ID against which you want to make the + * changes. + */ + snapshot_id?: string; + + /** + * Body param + */ + body_uris?: Array; + + [k: string]: unknown; +} + +export interface ItemListParams { + /** + * A comma-separated list of item types that your client supports besides the + * default `track` type. Valid types are: `track` and `episode`.
_**Note**: + * This parameter was introduced to allow existing clients to maintain their + * current behaviour and might be deprecated in the future._
In addition to + * providing this parameter, make sure that your client properly handles cases of + * new types in the future by checking against the `type` field of each object. + */ + additional_types?: string; + + /** + * Filters for the query: a comma-separated list of the fields to return. If + * omitted, all fields are returned. For example, to get just the total number of + * items and the request limit:
`fields=total,limit`
A dot separator can be + * used to specify non-reoccurring fields, while parentheses can be used to specify + * reoccurring fields within objects. For example, to get just the added date and + * user ID of the adder:
`fields=items(added_at,added_by.id)`
Use multiple + * parentheses to drill down into nested objects, for + * example:
`fields=items(track(name,href,album(name,href)))`
Fields can be + * excluded by prefixing them with an exclamation mark, for + * example:
`fields=items.track.album(!external_urls,images)` + */ + fields?: string; + + /** + * The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50. + */ + limit?: number; + + /** + * An + * [ISO 3166-1 alpha-2 country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). + * If a country code is specified, only content that is available in that market + * will be returned.
If a valid user access token is specified in the request + * header, the country associated with the user account will take priority over + * this parameter.
_**Note**: If neither market or user country are provided, + * the content is considered unavailable for the client._
Users can view the + * country that is associated with their account in the + * [account settings](https://www.spotify.com/account/overview/). + */ + market?: string; + + /** + * The index of the first item to return. Default: 0 (the first item). Use with + * limit to get the next set of items. + */ + offset?: number; +} + +export interface ItemAddParams { + /** + * Query param: The position to insert the items, a zero-based index. For example, + * to insert the items in the first position: `position=0`; to insert the items in + * the third position: `position=2`. If omitted, the items will be appended to the + * playlist. Items are added in the order they are listed in the query string or + * request body. + */ + query_position?: number; + + /** + * Query param: A comma-separated list of + * [Spotify URIs](/documentation/web-api/concepts/spotify-uris-ids) to add, can be + * track or episode URIs. For + * example:
`uris=spotify:track:4iV5W9uYEdYUVa79Axb7Rh, spotify:track:1301WleyT98MSxVHPZCA6M, spotify:episode:512ojhOuo1ktJprKbVcKyQ`
A + * maximum of 100 items can be added in one request.
_**Note**: it is likely + * that passing a large number of item URIs as a query parameter will exceed the + * maximum length of the request URI. When adding a large number of items, it is + * recommended to pass them in the request body, see below._ + */ + query_uris?: string; + + /** + * Body param: The position to insert the items, a zero-based index. For example, + * to insert the items in the first position: `position=0` ; to insert the items in + * the third position: `position=2`. If omitted, the items will be appended to the + * playlist. Items are added in the order they appear in the uris array. For + * example: + * `{"uris": ["spotify:track:4iV5W9uYEdYUVa79Axb7Rh","spotify:track:1301WleyT98MSxVHPZCA6M"], "position": 3}` + */ + body_position?: number; + + /** + * Body param: The playlist's public/private status (if it should be added to the + * user's profile or not): `true` the playlist will be public, `false` the playlist + * will be private, `null` the playlist status is not relevant. For more about + * public/private status, see + * [Working with Playlists](/documentation/web-api/concepts/playlists) + */ + published?: boolean; + + /** + * Body param: A JSON array of the + * [Spotify URIs](/documentation/web-api/concepts/spotify-uris-ids) to add. For + * example: + * `{"uris": ["spotify:track:4iV5W9uYEdYUVa79Axb7Rh","spotify:track:1301WleyT98MSxVHPZCA6M", "spotify:episode:512ojhOuo1ktJprKbVcKyQ"]}`
A + * maximum of 100 items can be added in one request. _**Note**: if the `uris` + * parameter is present in the query string, any URIs listed here in the body will + * be ignored._ + */ + body_uris?: Array; + + [k: string]: unknown; +} + +export interface ItemRemoveParams { + /** + * An array of objects containing + * [Spotify URIs](/documentation/web-api/concepts/spotify-uris-ids) of the tracks + * or episodes to remove. For example: + * `{ "items": [{ "uri": "spotify:track:4iV5W9uYEdYUVa79Axb7Rh" },{ "uri": "spotify:track:1301WleyT98MSxVHPZCA6M" }] }`. + * A maximum of 100 objects can be sent at once. + */ + items: Array; + + /** + * The playlist's public/private status (if it should be added to the user's + * profile or not): `true` the playlist will be public, `false` the playlist will + * be private, `null` the playlist status is not relevant. For more about + * public/private status, see + * [Working with Playlists](/documentation/web-api/concepts/playlists) + */ + published?: boolean; + + /** + * The playlist's snapshot ID against which you want to make the changes. The API + * will validate that the specified items exist and in the specified positions and + * make the changes, even if more recent changes have been made to the playlist. + */ + snapshot_id?: string; +} + +export namespace ItemRemoveParams { + export interface Item { + /** + * Spotify URI + */ + uri?: string; + } +} + +export declare namespace Items { + export { + type ItemUpdateResponse as ItemUpdateResponse, + type ItemAddResponse as ItemAddResponse, + type ItemRemoveResponse as ItemRemoveResponse, + type ItemUpdateParams as ItemUpdateParams, + type ItemListParams as ItemListParams, + type ItemAddParams as ItemAddParams, + type ItemRemoveParams as ItemRemoveParams, + }; +} + +export { type PlaylistTrackObjectsCursorURLPage }; diff --git a/src/resources/playlists/playlists.ts b/src/resources/playlists/playlists.ts index c805802..f84d48b 100644 --- a/src/resources/playlists/playlists.ts +++ b/src/resources/playlists/playlists.ts @@ -6,6 +6,17 @@ import * as FollowersAPI from './followers'; import { FollowerCheckParams, FollowerCheckResponse, FollowerFollowParams, Followers } from './followers'; import * as ImagesAPI from './images'; import { ImageListResponse, Images } from './images'; +import * as ItemsAPI from './items'; +import { + ItemAddParams, + ItemAddResponse, + ItemListParams, + ItemRemoveParams, + ItemRemoveResponse, + ItemUpdateParams, + ItemUpdateResponse, + Items as ItemsAPIItems, +} from './items'; import * as TracksAPI from './tracks'; import { TrackAddParams, @@ -26,6 +37,7 @@ export class Playlists extends APIResource { tracks: TracksAPI.Tracks = new TracksAPI.Tracks(this._client); followers: FollowersAPI.Followers = new FollowersAPI.Followers(this._client); images: ImagesAPI.Images = new ImagesAPI.Images(this._client); + items: ItemsAPI.Items = new ItemsAPI.Items(this._client); /** * Get a playlist owned by a Spotify user. @@ -109,6 +121,12 @@ export interface PlaylistRetrieveResponse { */ images?: Array; + /** + * The items of the playlist. _**Note**: This field is only available for playlists + * owned by the current user or playlists the user is a collaborator of._ + */ + items?: PlaylistRetrieveResponse.Items; + /** * The name of the playlist. */ @@ -135,7 +153,7 @@ export interface PlaylistRetrieveResponse { snapshot_id?: string; /** - * The tracks of the playlist. + * @deprecated **Deprecated:** Use `items` instead. The tracks of the playlist. */ tracks?: PlaylistRetrieveResponse.Tracks; @@ -152,6 +170,53 @@ export interface PlaylistRetrieveResponse { } export namespace PlaylistRetrieveResponse { + /** + * The items of the playlist. _**Note**: This field is only available for playlists + * owned by the current user or playlists the user is a collaborator of._ + */ + export interface Items { + /** + * A link to the Web API endpoint returning the full result of the request + */ + href: string; + + /** + * The maximum number of items in the response (as set in the query or by default). + */ + limit: number; + + /** + * URL to the next page of items. ( `null` if none) + */ + next: string | null; + + /** + * The offset of the items returned (as set in the query or by default) + */ + offset: number; + + /** + * URL to the previous page of items. ( `null` if none) + */ + previous: string | null; + + /** + * The total number of items available to return. + */ + total: number; + + items?: Array; + + /** + * The playlist's public/private status (if it should be added to the user's + * profile or not): `true` the playlist will be public, `false` the playlist will + * be private, `null` the playlist status is not relevant. For more about + * public/private status, see + * [Working with Playlists](/documentation/web-api/concepts/playlists) + */ + published?: boolean; + } + /** * The user who owns the playlist */ @@ -163,7 +228,7 @@ export namespace PlaylistRetrieveResponse { } /** - * The tracks of the playlist. + * @deprecated **Deprecated:** Use `items` instead. The tracks of the playlist. */ export interface Tracks { /** @@ -282,6 +347,7 @@ export interface PlaylistUpdateParams { Playlists.Tracks = TracksAPITracks; Playlists.Followers = Followers; Playlists.Images = Images; +Playlists.Items = ItemsAPIItems; export declare namespace Playlists { export { @@ -309,4 +375,15 @@ export declare namespace Playlists { }; export { Images as Images, type ImageListResponse as ImageListResponse }; + + export { + ItemsAPIItems as Items, + type ItemUpdateResponse as ItemUpdateResponse, + type ItemAddResponse as ItemAddResponse, + type ItemRemoveResponse as ItemRemoveResponse, + type ItemUpdateParams as ItemUpdateParams, + type ItemListParams as ItemListParams, + type ItemAddParams as ItemAddParams, + type ItemRemoveParams as ItemRemoveParams, + }; } diff --git a/src/resources/playlists/tracks.ts b/src/resources/playlists/tracks.ts index 358bad4..d12b298 100644 --- a/src/resources/playlists/tracks.ts +++ b/src/resources/playlists/tracks.ts @@ -10,6 +10,10 @@ import { path } from '../../internal/utils/path'; export class Tracks extends APIResource { /** + * **Deprecated:** Use + * [Update Playlist Items](/documentation/web-api/reference/reorder-or-replace-playlists-items) + * instead. + * * Either reorder or replace items in a playlist depending on the request's * parameters. To reorder items, include `range_start`, `insert_before`, * `range_length` and `snapshot_id` in the request's body. To replace items, @@ -20,12 +24,7 @@ export class Tracks extends APIResource { * have different parameters. These operations can't be applied together in a * single request. * - * @example - * ```ts - * const track = await client.playlists.tracks.update( - * '3cEYpjA9oz9GiPac4AsH4n', - * ); - * ``` + * @deprecated */ update( playlistID: string, @@ -36,17 +35,13 @@ export class Tracks extends APIResource { } /** + * **Deprecated:** Use + * [Get Playlist Items](/documentation/web-api/reference/get-playlists-items) + * instead. + * * Get full details of the items of a playlist owned by a Spotify user. * - * @example - * ```ts - * // Automatically fetches more pages as needed. - * for await (const playlistTrackObject of client.playlists.tracks.list( - * '3cEYpjA9oz9GiPac4AsH4n', - * )) { - * // ... - * } - * ``` + * @deprecated */ list( playlistID: string, @@ -61,14 +56,13 @@ export class Tracks extends APIResource { } /** + * **Deprecated:** Use + * [Add Items to Playlist](/documentation/web-api/reference/add-items-to-playlist) + * instead. + * * Add one or more items to a user's playlist. * - * @example - * ```ts - * const response = await client.playlists.tracks.add( - * '3cEYpjA9oz9GiPac4AsH4n', - * ); - * ``` + * @deprecated */ add( playlistID: string, @@ -79,15 +73,13 @@ export class Tracks extends APIResource { } /** + * **Deprecated:** Use + * [Remove Playlist Items](/documentation/web-api/reference/remove-items-playlist) + * instead. + * * Remove one or more items from a user's playlist. * - * @example - * ```ts - * const track = await client.playlists.tracks.remove( - * '3cEYpjA9oz9GiPac4AsH4n', - * { tracks: [{}] }, - * ); - * ``` + * @deprecated */ remove( playlistID: string, diff --git a/src/resources/search.ts b/src/resources/search.ts index 0137fc3..201eeb7 100644 --- a/src/resources/search.ts +++ b/src/resources/search.ts @@ -96,7 +96,7 @@ export namespace SearchQueryResponse { artists: Array; /** - * The markets in which the album is available: + * @deprecated The markets in which the album is available: * [ISO 3166-1 alpha-2 country codes](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). * _**NOTE**: an album is considered available in a market when at least 1 of its * tracks is available in that market._ diff --git a/src/resources/shared.ts b/src/resources/shared.ts index 2b98304..d92cf03 100644 --- a/src/resources/shared.ts +++ b/src/resources/shared.ts @@ -35,13 +35,13 @@ export interface ArtistObject { external_urls?: ExternalURLObject; /** - * Information about the followers of the artist. + * @deprecated Information about the followers of the artist. */ followers?: FollowersObject; /** - * A list of the genres the artist is associated with. If not yet classified, the - * array is empty. + * @deprecated A list of the genres the artist is associated with. If not yet + * classified, the array is empty. */ genres?: Array; @@ -61,8 +61,8 @@ export interface ArtistObject { name?: string; /** - * The popularity of the artist. The value will be between 0 and 100, with 100 - * being the most popular. The artist's popularity is calculated from the + * @deprecated The popularity of the artist. The value will be between 0 and 100, + * with 100 being the most popular. The artist's popularity is calculated from the * popularity of all the artist's tracks. */ popularity?: number; @@ -101,9 +101,9 @@ export interface AudiobookBase { authors: Array; /** - * A list of the countries in which the audiobook can be played, identified by - * their [ISO 3166-1 alpha-2](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) - * code. + * @deprecated A list of the countries in which the audiobook can be played, + * identified by their + * [ISO 3166-1 alpha-2](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code. */ available_markets: Array; @@ -166,7 +166,7 @@ export interface AudiobookBase { narrators: Array; /** - * The publisher of the audiobook. + * @deprecated The publisher of the audiobook. */ publisher: string; @@ -623,6 +623,11 @@ export interface PlaylistTrackObject { */ is_local?: boolean; + /** + * Information about the track or episode. + */ + item?: TrackObject | EpisodeObject; + /** * The playlist's public/private status (if it should be added to the user's * profile or not): `true` the playlist will be public, `false` the playlist will @@ -633,7 +638,8 @@ export interface PlaylistTrackObject { published?: boolean; /** - * Information about the track or episode. + * @deprecated **Deprecated:** Use `item` instead. Information about the track or + * episode. */ track?: TrackObject | EpisodeObject; } @@ -726,8 +732,9 @@ export interface ShowBase { id: string; /** - * A list of the countries in which the show can be played, identified by their - * [ISO 3166-1 alpha-2](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code. + * @deprecated A list of the countries in which the show can be played, identified + * by their [ISO 3166-1 alpha-2](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) + * code. */ available_markets: Array; @@ -791,7 +798,7 @@ export interface ShowBase { name: string; /** - * The publisher of the show. + * @deprecated The publisher of the show. */ publisher: string; @@ -1022,6 +1029,14 @@ export interface SimplifiedPlaylistObject { */ images?: Array; + /** + * A collection containing a link ( `href` ) to the Web API endpoint where full + * details of the playlist's items can be retrieved, along with the `total` number + * of items in the playlist. Note, a track object may be `null`. This can happen if + * a track is no longer available. + */ + items?: PlaylistTracksRefObject; + /** * The name of the playlist. */ @@ -1048,10 +1063,10 @@ export interface SimplifiedPlaylistObject { snapshot_id?: string; /** - * A collection containing a link ( `href` ) to the Web API endpoint where full - * details of the playlist's tracks can be retrieved, along with the `total` number - * of tracks in the playlist. Note, a track object may be `null`. This can happen - * if a track is no longer available. + * @deprecated **Deprecated:** Use `items` instead. A collection containing a link + * ( `href` ) to the Web API endpoint where full details of the playlist's tracks + * can be retrieved, along with the `total` number of tracks in the playlist. Note, + * a track object may be `null`. This can happen if a track is no longer available. */ tracks?: PlaylistTracksRefObject; @@ -1093,8 +1108,9 @@ export interface SimplifiedTrackObject { artists?: Array; /** - * A list of the countries in which the track can be played, identified by their - * [ISO 3166-1 alpha-2](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code. + * @deprecated A list of the countries in which the track can be played, identified + * by their [ISO 3166-1 alpha-2](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) + * code. */ available_markets?: Array; @@ -1137,7 +1153,7 @@ export interface SimplifiedTrackObject { is_playable?: boolean; /** - * Part of the response when + * @deprecated Part of the response when * [Track Relinking](/documentation/web-api/concepts/track-relinking/) is applied * and is only part of the response if the track linking, in fact, exists. The * requested track has been replaced with a different track. The track in the @@ -1207,8 +1223,9 @@ export interface TrackObject { artists?: Array; /** - * A list of the countries in which the track can be played, identified by their - * [ISO 3166-1 alpha-2](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) code. + * @deprecated A list of the countries in which the track can be played, identified + * by their [ISO 3166-1 alpha-2](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) + * code. */ available_markets?: Array; @@ -1229,7 +1246,7 @@ export interface TrackObject { explicit?: boolean; /** - * Known external IDs for the track. + * @deprecated Known external IDs for the track. */ external_ids?: ExternalIDObject; @@ -1256,7 +1273,7 @@ export interface TrackObject { is_playable?: boolean; /** - * Part of the response when + * @deprecated Part of the response when * [Track Relinking](/documentation/web-api/concepts/track-relinking) is applied, * and the requested track has been replaced with different track. The track in the * `linked_from` object contains information about the originally requested track. @@ -1269,16 +1286,16 @@ export interface TrackObject { name?: string; /** - * The popularity of the track. The value will be between 0 and 100, with 100 being - * the most popular.
The popularity of a track is a value between 0 and 100, - * with 100 being the most popular. The popularity is calculated by algorithm and - * is based, in the most part, on the total number of plays the track has had and - * how recent those plays are.
Generally speaking, songs that are being played - * a lot now will have a higher popularity than songs that were played a lot in the - * past. Duplicate tracks (e.g. the same track from a single and an album) are - * rated independently. Artist and album popularity is derived mathematically from - * track popularity. _**Note**: the popularity value may lag actual popularity by a - * few days: the value is not updated in real time._ + * @deprecated The popularity of the track. The value will be between 0 and 100, + * with 100 being the most popular.
The popularity of a track is a value + * between 0 and 100, with 100 being the most popular. The popularity is calculated + * by algorithm and is based, in the most part, on the total number of plays the + * track has had and how recent those plays are.
Generally speaking, songs that + * are being played a lot now will have a higher popularity than songs that were + * played a lot in the past. Duplicate tracks (e.g. the same track from a single + * and an album) are rated independently. Artist and album popularity is derived + * mathematically from track popularity. _**Note**: the popularity value may lag + * actual popularity by a few days: the value is not updated in real time._ */ popularity?: number; @@ -1344,7 +1361,7 @@ export namespace TrackObject { artists: Array; /** - * The markets in which the album is available: + * @deprecated The markets in which the album is available: * [ISO 3166-1 alpha-2 country codes](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). * _**NOTE**: an album is considered available in a market when at least 1 of its * tracks is available in that market._ diff --git a/src/resources/shows.ts b/src/resources/shows.ts index 65f5eff..1d2d471 100644 --- a/src/resources/shows.ts +++ b/src/resources/shows.ts @@ -23,6 +23,8 @@ export class Shows extends APIResource { /** * Get Spotify catalog information for several shows based on their Spotify IDs. + * + * @deprecated */ bulkRetrieve( query: ShowBulkRetrieveParams, diff --git a/src/resources/tracks.ts b/src/resources/tracks.ts index d0c5246..97db776 100644 --- a/src/resources/tracks.ts +++ b/src/resources/tracks.ts @@ -21,6 +21,8 @@ export class Tracks extends APIResource { /** * Get Spotify catalog information for multiple tracks based on their Spotify IDs. + * + * @deprecated */ bulkRetrieve( query: TrackBulkRetrieveParams, diff --git a/src/resources/users/playlists.ts b/src/resources/users/playlists.ts index 4163963..7276d3f 100644 --- a/src/resources/users/playlists.ts +++ b/src/resources/users/playlists.ts @@ -10,17 +10,14 @@ import { path } from '../../internal/utils/path'; export class Playlists extends APIResource { /** + * **Deprecated**: Use + * [Create Playlist](/documentation/web-api/reference/create-playlist) instead. + * * Create a playlist for a Spotify user. (The playlist will be empty until you * [add tracks](/documentation/web-api/reference/add-tracks-to-playlist).) Each * user is generally limited to a maximum of 11000 playlists. * - * @example - * ```ts - * const playlist = await client.users.playlists.create( - * 'smedjan', - * { name: 'New Playlist' }, - * ); - * ``` + * @deprecated */ create( userID: string, @@ -33,15 +30,7 @@ export class Playlists extends APIResource { /** * Get a list of the playlists owned or followed by a Spotify user. * - * @example - * ```ts - * // Automatically fetches more pages as needed. - * for await (const simplifiedPlaylistObject of client.users.playlists.list( - * 'smedjan', - * )) { - * // ... - * } - * ``` + * @deprecated */ list( userID: string, @@ -98,6 +87,12 @@ export interface PlaylistCreateResponse { */ images?: Array; + /** + * The items of the playlist. _**Note**: This field is only available for playlists + * owned by the current user or playlists the user is a collaborator of._ + */ + items?: PlaylistCreateResponse.Items; + /** * The name of the playlist. */ @@ -124,7 +119,7 @@ export interface PlaylistCreateResponse { snapshot_id?: string; /** - * The tracks of the playlist. + * @deprecated **Deprecated:** Use `items` instead. The tracks of the playlist. */ tracks?: PlaylistCreateResponse.Tracks; @@ -141,6 +136,53 @@ export interface PlaylistCreateResponse { } export namespace PlaylistCreateResponse { + /** + * The items of the playlist. _**Note**: This field is only available for playlists + * owned by the current user or playlists the user is a collaborator of._ + */ + export interface Items { + /** + * A link to the Web API endpoint returning the full result of the request + */ + href: string; + + /** + * The maximum number of items in the response (as set in the query or by default). + */ + limit: number; + + /** + * URL to the next page of items. ( `null` if none) + */ + next: string | null; + + /** + * The offset of the items returned (as set in the query or by default) + */ + offset: number; + + /** + * URL to the previous page of items. ( `null` if none) + */ + previous: string | null; + + /** + * The total number of items available to return. + */ + total: number; + + items?: Array; + + /** + * The playlist's public/private status (if it should be added to the user's + * profile or not): `true` the playlist will be public, `false` the playlist will + * be private, `null` the playlist status is not relevant. For more about + * public/private status, see + * [Working with Playlists](/documentation/web-api/concepts/playlists) + */ + published?: boolean; + } + /** * The user who owns the playlist */ @@ -152,7 +194,7 @@ export namespace PlaylistCreateResponse { } /** - * The tracks of the playlist. + * @deprecated **Deprecated:** Use `items` instead. The tracks of the playlist. */ export interface Tracks { /** diff --git a/src/resources/users/users.ts b/src/resources/users/users.ts index 031c6a8..cfeb59c 100644 --- a/src/resources/users/users.ts +++ b/src/resources/users/users.ts @@ -14,12 +14,7 @@ export class Users extends APIResource { /** * Get public profile information about a Spotify user. * - * @example - * ```ts - * const response = await client.users.retrieveProfile( - * 'smedjan', - * ); - * ``` + * @deprecated */ retrieveProfile(userID: string, options?: RequestOptions): APIPromise { return this._client.get(path`/users/${userID}`, options); @@ -44,7 +39,7 @@ export interface UserRetrieveProfileResponse { external_urls?: Shared.ExternalURLObject; /** - * Information about the followers of this user. + * @deprecated Information about the followers of this user. */ followers?: Shared.FollowersObject; diff --git a/src/version.ts b/src/version.ts index 1baa228..bade2ff 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '0.1.0'; // x-release-please-version +export const VERSION = '0.2.0'; // x-release-please-version diff --git a/tests/api-resources/albums.test.ts b/tests/api-resources/albums.test.ts index 57792d5..45a21f5 100644 --- a/tests/api-resources/albums.test.ts +++ b/tests/api-resources/albums.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/artists.test.ts b/tests/api-resources/artists.test.ts index b8adc9a..7b46129 100644 --- a/tests/api-resources/artists.test.ts +++ b/tests/api-resources/artists.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); @@ -61,7 +62,7 @@ describe('resource artists', () => { '0TnOYISbd1XYRBk9myaseg', { include_groups: 'single,appears_on', - limit: 10, + limit: 5, market: 'ES', offset: 5, }, diff --git a/tests/api-resources/audio-analysis.test.ts b/tests/api-resources/audio-analysis.test.ts index f60f0b0..dd6eb5a 100644 --- a/tests/api-resources/audio-analysis.test.ts +++ b/tests/api-resources/audio-analysis.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/audio-features.test.ts b/tests/api-resources/audio-features.test.ts index 845fca4..78c2837 100644 --- a/tests/api-resources/audio-features.test.ts +++ b/tests/api-resources/audio-features.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/audiobooks.test.ts b/tests/api-resources/audiobooks.test.ts index 543423a..461e225 100644 --- a/tests/api-resources/audiobooks.test.ts +++ b/tests/api-resources/audiobooks.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/browse/browse.test.ts b/tests/api-resources/browse/browse.test.ts index 4814dab..3bca0c8 100644 --- a/tests/api-resources/browse/browse.test.ts +++ b/tests/api-resources/browse/browse.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/browse/categories.test.ts b/tests/api-resources/browse/categories.test.ts index a837d87..27487de 100644 --- a/tests/api-resources/browse/categories.test.ts +++ b/tests/api-resources/browse/categories.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/chapters.test.ts b/tests/api-resources/chapters.test.ts index 67c4ca8..d64bef6 100644 --- a/tests/api-resources/chapters.test.ts +++ b/tests/api-resources/chapters.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/episodes.test.ts b/tests/api-resources/episodes.test.ts index bb9f6cf..7ef83c9 100644 --- a/tests/api-resources/episodes.test.ts +++ b/tests/api-resources/episodes.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/markets.test.ts b/tests/api-resources/markets.test.ts index 9ae9e4f..5a3a8e7 100644 --- a/tests/api-resources/markets.test.ts +++ b/tests/api-resources/markets.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/me/albums.test.ts b/tests/api-resources/me/albums.test.ts index f8b7cdc..a497ac1 100644 --- a/tests/api-resources/me/albums.test.ts +++ b/tests/api-resources/me/albums.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/me/audiobooks.test.ts b/tests/api-resources/me/audiobooks.test.ts index c9516ba..69d9db3 100644 --- a/tests/api-resources/me/audiobooks.test.ts +++ b/tests/api-resources/me/audiobooks.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/me/episodes.test.ts b/tests/api-resources/me/episodes.test.ts index b51ef70..52397f3 100644 --- a/tests/api-resources/me/episodes.test.ts +++ b/tests/api-resources/me/episodes.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/me/following.test.ts b/tests/api-resources/me/following.test.ts index 75ee26d..3c810de 100644 --- a/tests/api-resources/me/following.test.ts +++ b/tests/api-resources/me/following.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/me/library.test.ts b/tests/api-resources/me/library.test.ts new file mode 100644 index 0000000..95caf0f --- /dev/null +++ b/tests/api-resources/me/library.test.ts @@ -0,0 +1,74 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import Spotify from '@stainless-commons/spotify'; + +const client = new Spotify({ + clientID: 'My Client ID', + clientSecret: 'My Client Secret', + baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', +}); + +describe('resource library', () => { + // Prism tests are disabled + test.skip('checkSavedItems: only required params', async () => { + const responsePromise = client.me.library.checkSavedItems({ + uris: 'spotify:track:7a3LWj5xSFhFRYmztS8wgK,spotify:album:4aawyAB9vmqN3uQ7FjRGTy,spotify:artist:2takcwOaAZWiXQijPHIx7B', + }); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // Prism tests are disabled + test.skip('checkSavedItems: required and optional params', async () => { + const response = await client.me.library.checkSavedItems({ + uris: 'spotify:track:7a3LWj5xSFhFRYmztS8wgK,spotify:album:4aawyAB9vmqN3uQ7FjRGTy,spotify:artist:2takcwOaAZWiXQijPHIx7B', + }); + }); + + // Prism tests are disabled + test.skip('removeItems: only required params', async () => { + const responsePromise = client.me.library.removeItems({ + uris: 'spotify:track:7a3LWj5xSFhFRYmztS8wgK,spotify:album:4aawyAB9vmqN3uQ7FjRGTy', + }); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // Prism tests are disabled + test.skip('removeItems: required and optional params', async () => { + const response = await client.me.library.removeItems({ + uris: 'spotify:track:7a3LWj5xSFhFRYmztS8wgK,spotify:album:4aawyAB9vmqN3uQ7FjRGTy', + }); + }); + + // Prism tests are disabled + test.skip('saveItems: only required params', async () => { + const responsePromise = client.me.library.saveItems({ + uris: 'spotify:track:7a3LWj5xSFhFRYmztS8wgK,spotify:album:4aawyAB9vmqN3uQ7FjRGTy', + }); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // Prism tests are disabled + test.skip('saveItems: required and optional params', async () => { + const response = await client.me.library.saveItems({ + uris: 'spotify:track:7a3LWj5xSFhFRYmztS8wgK,spotify:album:4aawyAB9vmqN3uQ7FjRGTy', + }); + }); +}); diff --git a/tests/api-resources/me/me.test.ts b/tests/api-resources/me/me.test.ts index 1e13490..9971d3b 100644 --- a/tests/api-resources/me/me.test.ts +++ b/tests/api-resources/me/me.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/me/player/player.test.ts b/tests/api-resources/me/player/player.test.ts index 587efce..1df79c5 100644 --- a/tests/api-resources/me/player/player.test.ts +++ b/tests/api-resources/me/player/player.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/me/player/queue.test.ts b/tests/api-resources/me/player/queue.test.ts index 8a13793..c076227 100644 --- a/tests/api-resources/me/player/queue.test.ts +++ b/tests/api-resources/me/player/queue.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/me/playlists.test.ts b/tests/api-resources/me/playlists.test.ts index 5eb3236..e722bed 100644 --- a/tests/api-resources/me/playlists.test.ts +++ b/tests/api-resources/me/playlists.test.ts @@ -3,11 +3,34 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); describe('resource playlists', () => { + // Prism tests are disabled + test.skip('create: only required params', async () => { + const responsePromise = client.me.playlists.create({ name: 'New Playlist' }); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // Prism tests are disabled + test.skip('create: required and optional params', async () => { + const response = await client.me.playlists.create({ + name: 'New Playlist', + collaborative: true, + description: 'New playlist description', + published: true, + }); + }); + // Prism tests are disabled test.skip('list', async () => { const responsePromise = client.me.playlists.list(); diff --git a/tests/api-resources/me/shows.test.ts b/tests/api-resources/me/shows.test.ts index f5200b3..7f55d74 100644 --- a/tests/api-resources/me/shows.test.ts +++ b/tests/api-resources/me/shows.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/me/top.test.ts b/tests/api-resources/me/top.test.ts index d158a0c..d9aaae2 100644 --- a/tests/api-resources/me/top.test.ts +++ b/tests/api-resources/me/top.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/me/tracks.test.ts b/tests/api-resources/me/tracks.test.ts index 5ec7b44..543c500 100644 --- a/tests/api-resources/me/tracks.test.ts +++ b/tests/api-resources/me/tracks.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/playlists/followers.test.ts b/tests/api-resources/playlists/followers.test.ts index 883ff85..de4684f 100644 --- a/tests/api-resources/playlists/followers.test.ts +++ b/tests/api-resources/playlists/followers.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/playlists/images.test.ts b/tests/api-resources/playlists/images.test.ts index 6d303b0..2bda944 100644 --- a/tests/api-resources/playlists/images.test.ts +++ b/tests/api-resources/playlists/images.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/playlists/items.test.ts b/tests/api-resources/playlists/items.test.ts new file mode 100644 index 0000000..9463c42 --- /dev/null +++ b/tests/api-resources/playlists/items.test.ts @@ -0,0 +1,124 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import Spotify from '@stainless-commons/spotify'; + +const client = new Spotify({ + clientID: 'My Client ID', + clientSecret: 'My Client Secret', + baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', +}); + +describe('resource items', () => { + // Prism tests are disabled + test.skip('update', async () => { + const responsePromise = client.playlists.items.update('3cEYpjA9oz9GiPac4AsH4n'); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // Prism tests are disabled + test.skip('update: request options and params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect( + client.playlists.items.update( + '3cEYpjA9oz9GiPac4AsH4n', + { + query_uris: 'uris', + insert_before: 3, + published: true, + range_length: 2, + range_start: 1, + snapshot_id: 'snapshot_id', + body_uris: ['string'], + }, + { path: '/_stainless_unknown_path' }, + ), + ).rejects.toThrow(Spotify.NotFoundError); + }); + + // Prism tests are disabled + test.skip('list', async () => { + const responsePromise = client.playlists.items.list('3cEYpjA9oz9GiPac4AsH4n'); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // Prism tests are disabled + test.skip('list: request options and params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect( + client.playlists.items.list( + '3cEYpjA9oz9GiPac4AsH4n', + { + additional_types: 'additional_types', + fields: 'items(added_by.id,track(name,href,album(name,href)))', + limit: 10, + market: 'ES', + offset: 5, + }, + { path: '/_stainless_unknown_path' }, + ), + ).rejects.toThrow(Spotify.NotFoundError); + }); + + // Prism tests are disabled + test.skip('add', async () => { + const responsePromise = client.playlists.items.add('3cEYpjA9oz9GiPac4AsH4n'); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // Prism tests are disabled + test.skip('add: request options and params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect( + client.playlists.items.add( + '3cEYpjA9oz9GiPac4AsH4n', + { + query_position: 0, + query_uris: 'spotify:track:4iV5W9uYEdYUVa79Axb7Rh,spotify:track:1301WleyT98MSxVHPZCA6M', + body_position: 0, + published: true, + body_uris: ['string'], + }, + { path: '/_stainless_unknown_path' }, + ), + ).rejects.toThrow(Spotify.NotFoundError); + }); + + // Prism tests are disabled + test.skip('remove: only required params', async () => { + const responsePromise = client.playlists.items.remove('3cEYpjA9oz9GiPac4AsH4n', { items: [{}] }); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // Prism tests are disabled + test.skip('remove: required and optional params', async () => { + const response = await client.playlists.items.remove('3cEYpjA9oz9GiPac4AsH4n', { + items: [{ uri: 'uri' }], + published: true, + snapshot_id: 'snapshot_id', + }); + }); +}); diff --git a/tests/api-resources/playlists/playlists.test.ts b/tests/api-resources/playlists/playlists.test.ts index 2a27ffb..474806e 100644 --- a/tests/api-resources/playlists/playlists.test.ts +++ b/tests/api-resources/playlists/playlists.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/playlists/tracks.test.ts b/tests/api-resources/playlists/tracks.test.ts index a6b8a38..ffb196e 100644 --- a/tests/api-resources/playlists/tracks.test.ts +++ b/tests/api-resources/playlists/tracks.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/recommendations.test.ts b/tests/api-resources/recommendations.test.ts index 50377fb..5164d8e 100644 --- a/tests/api-resources/recommendations.test.ts +++ b/tests/api-resources/recommendations.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/search.test.ts b/tests/api-resources/search.test.ts index 0f27802..5e81e1e 100644 --- a/tests/api-resources/search.test.ts +++ b/tests/api-resources/search.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/shows.test.ts b/tests/api-resources/shows.test.ts index ef13cc8..50b163f 100644 --- a/tests/api-resources/shows.test.ts +++ b/tests/api-resources/shows.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/tracks.test.ts b/tests/api-resources/tracks.test.ts index 6feb327..14b821e 100644 --- a/tests/api-resources/tracks.test.ts +++ b/tests/api-resources/tracks.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/users/playlists.test.ts b/tests/api-resources/users/playlists.test.ts index 181fe7a..7f40a15 100644 --- a/tests/api-resources/users/playlists.test.ts +++ b/tests/api-resources/users/playlists.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/api-resources/users/users.test.ts b/tests/api-resources/users/users.test.ts index 0fe38e7..6071726 100644 --- a/tests/api-resources/users/users.test.ts +++ b/tests/api-resources/users/users.test.ts @@ -3,7 +3,8 @@ import Spotify from '@stainless-commons/spotify'; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', }); diff --git a/tests/index.test.ts b/tests/index.test.ts index df1c9bf..1e9db8b 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -23,7 +23,8 @@ describe('instantiate client', () => { const client = new Spotify({ baseURL: 'http://localhost:5000/', defaultHeaders: { 'X-My-Default-Header': '2' }, - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', }); test('they are used in the request', async () => { @@ -90,7 +91,8 @@ describe('instantiate client', () => { const client = new Spotify({ logger: logger, logLevel: 'debug', - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', }); await forceAPIResponseForClient(client); @@ -98,7 +100,7 @@ describe('instantiate client', () => { }); test('default logLevel is warn', async () => { - const client = new Spotify({ accessToken: 'My Access Token' }); + const client = new Spotify({ clientID: 'My Client ID', clientSecret: 'My Client Secret' }); expect(client.logLevel).toBe('warn'); }); @@ -114,7 +116,8 @@ describe('instantiate client', () => { const client = new Spotify({ logger: logger, logLevel: 'info', - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', }); await forceAPIResponseForClient(client); @@ -131,7 +134,11 @@ describe('instantiate client', () => { }; process.env['SPOTIFY_LOG'] = 'debug'; - const client = new Spotify({ logger: logger, accessToken: 'My Access Token' }); + const client = new Spotify({ + logger: logger, + clientID: 'My Client ID', + clientSecret: 'My Client Secret', + }); expect(client.logLevel).toBe('debug'); await forceAPIResponseForClient(client); @@ -148,7 +155,11 @@ describe('instantiate client', () => { }; process.env['SPOTIFY_LOG'] = 'not a log level'; - const client = new Spotify({ logger: logger, accessToken: 'My Access Token' }); + const client = new Spotify({ + logger: logger, + clientID: 'My Client ID', + clientSecret: 'My Client Secret', + }); expect(client.logLevel).toBe('warn'); expect(warnMock).toHaveBeenCalledWith( 'process.env[\'SPOTIFY_LOG\'] was set to "not a log level", expected one of ["off","error","warn","info","debug"]', @@ -168,7 +179,8 @@ describe('instantiate client', () => { const client = new Spotify({ logger: logger, logLevel: 'off', - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', }); await forceAPIResponseForClient(client); @@ -188,7 +200,8 @@ describe('instantiate client', () => { const client = new Spotify({ logger: logger, logLevel: 'debug', - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', }); expect(client.logLevel).toBe('debug'); expect(warnMock).not.toHaveBeenCalled(); @@ -200,7 +213,8 @@ describe('instantiate client', () => { const client = new Spotify({ baseURL: 'http://localhost:5000/', defaultQuery: { apiVersion: 'foo' }, - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', }); expect(client.buildURL('/foo', null)).toEqual('http://localhost:5000/foo?apiVersion=foo'); }); @@ -209,7 +223,8 @@ describe('instantiate client', () => { const client = new Spotify({ baseURL: 'http://localhost:5000/', defaultQuery: { apiVersion: 'foo', hello: 'world' }, - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', }); expect(client.buildURL('/foo', null)).toEqual('http://localhost:5000/foo?apiVersion=foo&hello=world'); }); @@ -218,7 +233,8 @@ describe('instantiate client', () => { const client = new Spotify({ baseURL: 'http://localhost:5000/', defaultQuery: { hello: 'world' }, - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', }); expect(client.buildURL('/foo', { hello: undefined })).toEqual('http://localhost:5000/foo'); }); @@ -227,7 +243,8 @@ describe('instantiate client', () => { test('custom fetch', async () => { const client = new Spotify({ baseURL: 'http://localhost:5000/', - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', fetch: (url) => { return Promise.resolve( new Response(JSON.stringify({ url, custom: true }), { @@ -245,7 +262,8 @@ describe('instantiate client', () => { // make sure the global fetch type is assignable to our Fetch type const client = new Spotify({ baseURL: 'http://localhost:5000/', - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', fetch: defaultFetch, }); }); @@ -253,7 +271,8 @@ describe('instantiate client', () => { test('custom signal', async () => { const client = new Spotify({ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', fetch: (...args) => { return new Promise((resolve, reject) => setTimeout( @@ -285,7 +304,8 @@ describe('instantiate client', () => { const client = new Spotify({ baseURL: 'http://localhost:5000/', - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', fetch: testFetch, }); @@ -297,7 +317,8 @@ describe('instantiate client', () => { test('trailing slash', () => { const client = new Spotify({ baseURL: 'http://localhost:5000/custom/path/', - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', }); expect(client.buildURL('/foo', null)).toEqual('http://localhost:5000/custom/path/foo'); }); @@ -305,7 +326,8 @@ describe('instantiate client', () => { test('no trailing slash', () => { const client = new Spotify({ baseURL: 'http://localhost:5000/custom/path', - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', }); expect(client.buildURL('/foo', null)).toEqual('http://localhost:5000/custom/path/foo'); }); @@ -315,37 +337,45 @@ describe('instantiate client', () => { }); test('explicit option', () => { - const client = new Spotify({ baseURL: 'https://example.com', accessToken: 'My Access Token' }); + const client = new Spotify({ + baseURL: 'https://example.com', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', + }); expect(client.baseURL).toEqual('https://example.com'); }); test('env variable', () => { process.env['SPOTIFY_BASE_URL'] = 'https://example.com/from_env'; - const client = new Spotify({ accessToken: 'My Access Token' }); + const client = new Spotify({ clientID: 'My Client ID', clientSecret: 'My Client Secret' }); expect(client.baseURL).toEqual('https://example.com/from_env'); }); test('empty env variable', () => { process.env['SPOTIFY_BASE_URL'] = ''; // empty - const client = new Spotify({ accessToken: 'My Access Token' }); + const client = new Spotify({ clientID: 'My Client ID', clientSecret: 'My Client Secret' }); expect(client.baseURL).toEqual('https://api.spotify.com/v1'); }); test('blank env variable', () => { process.env['SPOTIFY_BASE_URL'] = ' '; // blank - const client = new Spotify({ accessToken: 'My Access Token' }); + const client = new Spotify({ clientID: 'My Client ID', clientSecret: 'My Client Secret' }); expect(client.baseURL).toEqual('https://api.spotify.com/v1'); }); test('in request options', () => { - const client = new Spotify({ accessToken: 'My Access Token' }); + const client = new Spotify({ clientID: 'My Client ID', clientSecret: 'My Client Secret' }); expect(client.buildURL('/foo', null, 'http://localhost:5000/option')).toEqual( 'http://localhost:5000/option/foo', ); }); test('in request options overridden by client options', () => { - const client = new Spotify({ accessToken: 'My Access Token', baseURL: 'http://localhost:5000/client' }); + const client = new Spotify({ + clientID: 'My Client ID', + clientSecret: 'My Client Secret', + baseURL: 'http://localhost:5000/client', + }); expect(client.buildURL('/foo', null, 'http://localhost:5000/option')).toEqual( 'http://localhost:5000/client/foo', ); @@ -353,7 +383,7 @@ describe('instantiate client', () => { test('in request options overridden by env variable', () => { process.env['SPOTIFY_BASE_URL'] = 'http://localhost:5000/env'; - const client = new Spotify({ accessToken: 'My Access Token' }); + const client = new Spotify({ clientID: 'My Client ID', clientSecret: 'My Client Secret' }); expect(client.buildURL('/foo', null, 'http://localhost:5000/option')).toEqual( 'http://localhost:5000/env/foo', ); @@ -361,11 +391,15 @@ describe('instantiate client', () => { }); test('maxRetries option is correctly set', () => { - const client = new Spotify({ maxRetries: 4, accessToken: 'My Access Token' }); + const client = new Spotify({ + maxRetries: 4, + clientID: 'My Client ID', + clientSecret: 'My Client Secret', + }); expect(client.maxRetries).toEqual(4); // default - const client2 = new Spotify({ accessToken: 'My Access Token' }); + const client2 = new Spotify({ clientID: 'My Client ID', clientSecret: 'My Client Secret' }); expect(client2.maxRetries).toEqual(2); }); @@ -374,7 +408,8 @@ describe('instantiate client', () => { const client = new Spotify({ baseURL: 'http://localhost:5000/', maxRetries: 3, - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', }); const newClient = client.withOptions({ @@ -400,7 +435,8 @@ describe('instantiate client', () => { baseURL: 'http://localhost:5000/', defaultHeaders: { 'X-Test-Header': 'test-value' }, defaultQuery: { 'test-param': 'test-value' }, - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', }); const newClient = client.withOptions({ @@ -418,7 +454,8 @@ describe('instantiate client', () => { const client = new Spotify({ baseURL: 'http://localhost:5000/', timeout: 1000, - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', }); // Modify the client properties directly after creation @@ -447,21 +484,25 @@ describe('instantiate client', () => { test('with environment variable arguments', () => { // set options via env var - process.env['SPOTIFY_ACCESS_TOKEN'] = 'My Access Token'; + process.env['SPOTIFY_CLIENT_ID'] = 'My Client ID'; + process.env['SPOTIFY_CLIENT_SECRET'] = 'My Client Secret'; const client = new Spotify(); - expect(client.accessToken).toBe('My Access Token'); + expect(client.clientID).toBe('My Client ID'); + expect(client.clientSecret).toBe('My Client Secret'); }); test('with overridden environment variable arguments', () => { // set options via env var - process.env['SPOTIFY_ACCESS_TOKEN'] = 'another My Access Token'; - const client = new Spotify({ accessToken: 'My Access Token' }); - expect(client.accessToken).toBe('My Access Token'); + process.env['SPOTIFY_CLIENT_ID'] = 'another My Client ID'; + process.env['SPOTIFY_CLIENT_SECRET'] = 'another My Client Secret'; + const client = new Spotify({ clientID: 'My Client ID', clientSecret: 'My Client Secret' }); + expect(client.clientID).toBe('My Client ID'); + expect(client.clientSecret).toBe('My Client Secret'); }); }); describe('request building', () => { - const client = new Spotify({ accessToken: 'My Access Token' }); + const client = new Spotify({ clientID: 'My Client ID', clientSecret: 'My Client Secret' }); describe('custom headers', () => { test('handles undefined', async () => { @@ -480,7 +521,7 @@ describe('request building', () => { }); describe('default encoder', () => { - const client = new Spotify({ accessToken: 'My Access Token' }); + const client = new Spotify({ clientID: 'My Client ID', clientSecret: 'My Client Secret' }); class Serializable { toJSON() { @@ -566,7 +607,8 @@ describe('retries', () => { }; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', timeout: 10, fetch: testFetch, }); @@ -600,7 +642,8 @@ describe('retries', () => { }; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', fetch: testFetch, maxRetries: 4, }); @@ -628,7 +671,8 @@ describe('retries', () => { return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } }); }; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', fetch: testFetch, maxRetries: 4, }); @@ -661,7 +705,8 @@ describe('retries', () => { return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } }); }; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', fetch: testFetch, maxRetries: 4, defaultHeaders: { 'X-Stainless-Retry-Count': null }, @@ -694,7 +739,8 @@ describe('retries', () => { return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } }); }; const client = new Spotify({ - accessToken: 'My Access Token', + clientID: 'My Client ID', + clientSecret: 'My Client Secret', fetch: testFetch, maxRetries: 4, }); @@ -727,7 +773,11 @@ describe('retries', () => { return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } }); }; - const client = new Spotify({ accessToken: 'My Access Token', fetch: testFetch }); + const client = new Spotify({ + clientID: 'My Client ID', + clientSecret: 'My Client Secret', + fetch: testFetch, + }); expect(await client.request({ path: '/foo', method: 'get' })).toEqual({ a: 1 }); expect(count).toEqual(2); @@ -757,7 +807,11 @@ describe('retries', () => { return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } }); }; - const client = new Spotify({ accessToken: 'My Access Token', fetch: testFetch }); + const client = new Spotify({ + clientID: 'My Client ID', + clientSecret: 'My Client Secret', + fetch: testFetch, + }); expect(await client.request({ path: '/foo', method: 'get' })).toEqual({ a: 1 }); expect(count).toEqual(2);