Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@soundify/api

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@soundify/api - npm Package Compare versions

Comparing version 0.1.0-alpha.3 to 0.1.1-beta.0

75

esm/client.js

@@ -1,2 +0,2 @@

import { objectToSearchParams, } from "@soundify/shared";
import { toQueryString } from "@soundify/shared";
/**

@@ -10,3 +10,3 @@ * The Spotify client will throw this error if the api response is not "ok" (status >= 400)

this.status = status;
this.name = "SpotifyError" + status;
this.name = "SpotifyError";
}

@@ -20,9 +20,11 @@ }

opts;
constructor(
BASE_HEADERS = {
"Content-Type": "application/json",
"Accept": "application/json",
};
/**
* It is recommended to pass a class that implements `IAuthProvider`
* to automatically update tokens. If you do not need this behavior,
* you can simply pass an access token.
* @param authProvider It is recommended to pass a class that implements `IAuthProvider` to automatically update tokens. If you do not need this behavior,you can simply pass an access token.
* @param opts Additional options for fetch execution, such as the ability to retry on error
*/
authProvider, opts = {
constructor(authProvider, opts = {
retryOnRateLimit: false,

@@ -41,37 +43,31 @@ retryDelayOn5xx: 0,

}
async fetch(baseURL, responseType, { body, query, method, headers } = {}) {
async fetch(baseURL, responseType, { json, query, method, headers, body } = {}) {
const url = new URL("https://api.spotify.com/v1" + baseURL);
if (query) {
url.search = objectToSearchParams(query).toString();
url.search = toQueryString(query);
}
const serializedBody = body ? JSON.stringify(body) : undefined;
const mergedHeaders = new Headers({
"Content-Type": "application/json",
"Accept": "application/json",
...headers,
});
const _body = body ? body : json ? JSON.stringify(json) : undefined;
const _headers = new Headers(this.BASE_HEADERS);
if (headers) {
Object.entries(headers).forEach(([name, value]) => _headers.append(name, value));
}
let isTriedRefreshToken = false;
let retryTimesOn5xx = this.opts.retryTimesOn5xx;
let accessToken = typeof this.authProvider === "string"
? this.authProvider
: await this.authProvider.getAccessToken();
let accessToken = typeof this.authProvider === "object"
? this.authProvider.getToken()
: this.authProvider;
const call = async () => {
mergedHeaders.set("Authorization", "Bearer " + accessToken);
_headers.set("Authorization", "Bearer " + accessToken);
const res = await fetch(url, {
method,
headers: mergedHeaders,
body: serializedBody,
headers: _headers,
body: _body,
});
if (res.ok)
return res;
if (res.status === 401 && typeof this.authProvider !== "string" &&
if (res.status === 401 && typeof this.authProvider === "object" &&
!isTriedRefreshToken) {
try {
accessToken = await this.authProvider.getAccessToken(true);
isTriedRefreshToken = true;
return call();
}
catch (e) {
throw new SpotifyError((await res.json()).error.message, res.status, { cause: e });
}
accessToken = await this.authProvider.refreshToken();
isTriedRefreshToken = true;
return call();
}

@@ -93,11 +89,26 @@ if (res.status === 429 && this.opts.retryOnRateLimit) {

}
throw new SpotifyError((await res.json()).error.message, res.status);
let message;
if (!res.body) {
message = "Empty error";
}
else {
const text = await res.text();
try {
message = JSON.parse(text).error.message;
}
catch (_) {
message = text;
}
}
throw new SpotifyError(message, res.status);
};
const res = await call();
if (responseType === "json") {
if (!res.body)
throw new Error("Not found body");
return await res.json();
}
if (res.body)
res.body.cancel();
await res.body.cancel();
}
}

@@ -23,3 +23,3 @@ /**

method: "PUT",
body,
json: body,
});

@@ -77,3 +77,3 @@ };

method: "PUT",
body: opts,
json: opts,
});

@@ -92,5 +92,3 @@ };

method: "PUT",
body: {
uris,
},
json: { uris },
});

@@ -109,3 +107,3 @@ };

method: "DELETE",
body: {
json: {
tracks: uris.map((uri) => ({ uri })),

@@ -159,3 +157,3 @@ snapshot_id,

return await client.fetch(`/users/${user_id}/playlists`, "json", {
body,
json: body,
method: "POST",

@@ -162,0 +160,0 @@ });

@@ -13,2 +13,4 @@ /**

*
* @requires `user-top-read`
*
* @param client Spotify HTTPClient

@@ -26,2 +28,4 @@ * @param type The type of entity to return. ("artists" or "tracks")

*
* @requires `user-top-read`
*
* @param client Spotify HTTPClient

@@ -36,2 +40,4 @@ * @param opts Additional option for request

*
* @requires `user-top-read`
*
* @param client Spotify HTTPClient

@@ -55,2 +61,4 @@ * @param opts Additional option for request

*
* @requires `playlist-modify-public` or `playlist-modify-private`
*
* @param client Spotify HTTPClient

@@ -64,3 +72,3 @@ * @param playlist_id Spotify playlist ID

method: "PUT",
body: { public: is_public },
json: { public: is_public },
});

@@ -71,2 +79,4 @@ };

*
* @requires `playlist-modify-public` or `playlist-modify-private`
*
* @param client Spotify HTTPClient

@@ -81,2 +91,4 @@ * @param playlist_id Spotify playlist ID

*
* @requires `user-follow-read`
*
* @param client Spotify HTTPClient

@@ -96,2 +108,4 @@ * @param opts Additional option for request

*
* @requires `user-follow-modify`
*
* @param client Spotify HTTPClient

@@ -112,2 +126,4 @@ * @param artist_ids List of Spotify artist IDs. Maximum 50

*
* @requires `user-follow-modify`
*
* @param client Spotify HTTPClient

@@ -122,2 +138,4 @@ * @param artist_id Spotify artist ID

*
* @requires `user-follow-modify`
*
* @param client Spotify HTTPClient

@@ -138,2 +156,4 @@ * @param artist_ids List of Spotify user IDs. Maximum 50

*
* @requires `user-follow-modify`
*
* @param client Spotify HTTPClient

@@ -148,2 +168,4 @@ * @param artist_id Spotify user ID

*
* @requires `user-follow-modify`
*
* @param client Spotify HTTPClient

@@ -164,2 +186,4 @@ * @param artist_ids List of Spotify artist IDs. Maximum 50

*
* @requires `user-follow-modify`
*
* @param client Spotify HTTPClient

@@ -174,2 +198,4 @@ * @param artist_id Spotify artist ID

*
* @requires `user-follow-modify`
*
* @param client Spotify HTTPClient

@@ -190,2 +216,4 @@ * @param user_ids List of Spotify user IDs. Maximum 50

*
* @requires `user-follow-modify`
*
* @param client Spotify HTTPClient

@@ -200,2 +228,4 @@ * @param artist_id Spotify user ID

*
* @requires `user-follow-read`
*
* @param client Spotify HTTPClient

@@ -215,2 +245,4 @@ * @param artist_ids List of Spotify artist IDs. Maximum 50

*
* @requires `user-follow-read`
*
* @param client Spotify HTTPClient

@@ -225,2 +257,4 @@ * @param artist_id Spotify artist ID

*
* @requires `user-follow-read`
*
* @param client Spotify HTTPClient

@@ -240,2 +274,4 @@ * @param user_ids List of Spotify user IDs. Maximum 50

*
* @requires `user-follow-read`
*
* @param client Spotify HTTPClient

@@ -242,0 +278,0 @@ * @param user_id Spotify user ID

@@ -5,10 +5,7 @@ {

"name": "@soundify/api",
"version": "0.1.0-alpha.3",
"version": "0.1.1-beta.0",
"description": "🎧 Modern Spotify api wrapper for Node, Deno, and browser",
"license": "MIT",
"devDependencies": {
"@types/node": "latest"
},
"dependencies": {
"@soundify/shared": "0.1.0-alpha.3"
"@soundify/shared": "0.1.1-beta.0"
},

@@ -15,0 +12,0 @@ "packageManager": "pnpm@7.30.0",

@@ -1,2 +0,2 @@

import { HTTPClient } from "@soundify/shared";
import { HTTPClient } from "../client.js";
import { PagingObject, PagingOptions } from "../general.types.js";

@@ -3,0 +3,0 @@ import { Market } from "../market/market.types.js";

@@ -6,3 +6,3 @@ import { Copyright, ExternalIds, ExternalUrls, Image, PagingObject, RestrictionsReason } from "../general.types.js";

import { Genre } from "../genre/genre.types.js";
import { JSONObject } from "@soundify/shared";
import { JSONObject } from "../general.types.js";
/**

@@ -9,0 +9,0 @@ * The types of album.

import * as endpoints from "./endpoints.js";
import { HTTPClient } from "@soundify/shared";
import { HTTPClient } from "./client.js";
type OmitFirst<T extends unknown[]> = T extends [unknown, ...infer R] ? R : never;

@@ -4,0 +4,0 @@ export type ISpoitfyAPI = {

@@ -1,2 +0,2 @@

import { HTTPClient } from "@soundify/shared";
import { HTTPClient } from "../client.js";
import { PagingObject, PagingOptions } from "../general.types.js";

@@ -7,2 +7,3 @@ import { AlbumGroup, AlbumSimplified } from "../album/album.types.js";

import { Artist } from "./artist.types.js";
import { SearchParams } from "@soundify/shared";
/**

@@ -22,3 +23,3 @@ * Get Spotify catalog information for a single artist identified by their unique Spotify ID.

export declare const getArtists: (client: HTTPClient, artist_ids: string[]) => Promise<Artist[]>;
interface GetArtistAlbumsOpts extends PagingOptions {
interface GetArtistAlbumsOpts extends PagingOptions, SearchParams {
/**

@@ -25,0 +26,0 @@ * List of keywords that will be used to filter the response.

@@ -1,2 +0,2 @@

import { JSONObject } from "@soundify/shared";
import { JSONObject } from "../general.types.js";
import { ExternalUrls, Followers, Image } from "../general.types.js";

@@ -3,0 +3,0 @@ export interface ArtistSimplified extends JSONObject {

@@ -1,5 +0,6 @@

import { HTTPClient, SearchParams } from "@soundify/shared";
import { SearchParams } from "@soundify/shared";
import { PagingObject } from "../general.types.js";
import { Market } from "../market/market.types.js";
import { Category } from "./category.types.js";
import { HTTPClient } from "../client.js";
interface GetBrowseCategoriesOpts extends SearchParams {

@@ -6,0 +7,0 @@ /**

@@ -1,2 +0,2 @@

import { JSONObject, NonNullableJSON } from "@soundify/shared";
import { JSONObject, NonNullableJSON } from "../general.types.js";
import { Image } from "../general.types.js";

@@ -3,0 +3,0 @@ export interface Category extends JSONObject {

@@ -1,3 +0,46 @@

import { FetchOpts, HTTPClient, IAuthProvider, JSONValue } from "@soundify/shared";
import { IAuthProvider, SearchParams } from "@soundify/shared";
import { JSONValue } from "./general.types.js";
type HTTPMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
/**
* Options for fetch method on HTTPClient interface
*/
export interface FetchOpts {
method?: HTTPMethod;
/**
* Json object that will be stringified and passed to the body of the request.
* Will be ignored if `body` is specified.
*/
json?: JSONValue;
/**
* Query parameters or, more precisely, search parameters that will be converted into a query string and passed to the url.
*/
query?: SearchParams;
/**
* Custom headers that will be passed to the request and overwrite existing ones
*/
headers?: HeadersInit;
/**
* Request body. Will overwrite `json` property if specified.
*/
body?: BodyInit;
}
export type ExpectedResponse = "json" | "void";
/**
* Interface that provides a fetch method to make HTTP requests to Spotify API.
*/
export interface HTTPClient {
/**
* Sends an HTTP request.
*
* @param baseURL
* The base URL for the API request. Must begin with "/"
* @param returnType
* The expected return type of the API response.
* @param opts
* Optional request options, such as the request body or query parameters.
*/
fetch(baseURL: string, responseType: "void", opts?: FetchOpts): Promise<void>;
fetch<R extends JSONValue = JSONValue>(baseURL: string, responseType: "json", opts?: FetchOpts): Promise<R>;
}
/**
* The Spotify client will throw this error if the api response is not "ok" (status >= 400)

@@ -34,16 +77,10 @@ */

export declare class SpotifyClient implements HTTPClient {
/**
* It is recommended to pass a class that implements `IAuthProvider`
* to automatically update tokens. If you do not need this behavior,
* you can simply pass an access token.
*/
private authProvider;
private readonly opts;
constructor(
private BASE_HEADERS;
/**
* It is recommended to pass a class that implements `IAuthProvider`
* to automatically update tokens. If you do not need this behavior,
* you can simply pass an access token.
* @param authProvider It is recommended to pass a class that implements `IAuthProvider` to automatically update tokens. If you do not need this behavior,you can simply pass an access token.
* @param opts Additional options for fetch execution, such as the ability to retry on error
*/
authProvider: IAuthProvider | string, opts?: SpotifyClientOpts);
constructor(authProvider: IAuthProvider | string, opts?: SpotifyClientOpts);
/**

@@ -53,4 +90,5 @@ * Method that changes the existing authProvider to the specified one

setAuthProvider(authProvider: IAuthProvider | string): void;
fetch(baseURL: string, responseType: "void", opts?: FetchOpts): Promise<void>;
fetch(baseURL: string, hasResponse: "void", opts?: FetchOpts): Promise<void>;
fetch<R extends JSONValue = JSONValue>(baseURL: string, responseType: "json", opts?: FetchOpts): Promise<R>;
}
export {};

@@ -1,2 +0,2 @@

import { JSONObject, SearchParams } from "@soundify/shared";
import { SearchParams } from "@soundify/shared";
export interface PagingObject<T extends JSONObject> extends JSONObject {

@@ -137,1 +137,9 @@ /**

}
export type NonNullableJSON<T extends JSONObject> = {
[K in keyof T]: NonNullable<T[K]>;
};
export type JSONValue = null | string | number | boolean | JSONObject | JSONArray;
export type JSONArray = JSONValue[];
export interface JSONObject {
[x: string]: JSONValue | undefined;
}

@@ -1,2 +0,2 @@

import { HTTPClient } from "@soundify/shared";
import { HTTPClient } from "../client.js";
import { Genre } from "./genre.types.js";

@@ -3,0 +3,0 @@ /**

@@ -1,2 +0,2 @@

import { HTTPClient } from "@soundify/shared";
import { HTTPClient } from "../client.js";
import { Market } from "./market.types.js";

@@ -3,0 +3,0 @@ /**

@@ -1,5 +0,7 @@

import { HTTPClient, JSONObject, NonNullableJSON, SearchParams } from "@soundify/shared";
import { SearchParams } from "@soundify/shared";
import { Market } from "../market/market.types.js";
import { Image, PagingObject, PagingOptions } from "../general.types.js";
import { FeaturedPlaylists, Playlist, PlaylistSimplified, PlaylistTrack } from "./playlist.types.js";
import { HTTPClient } from "../client.js";
import { JSONObject, NonNullableJSON } from "../general.types.js";
interface PlaylistFieldsOpts extends SearchParams {

@@ -6,0 +8,0 @@ /**

import { ExternalUrls, Followers, Image, PagingObject } from "../general.types.js";
import { UserPublic } from "../user/user.types.js";
import { Track } from "../track/track.types.js";
import { JSONObject } from "@soundify/shared";
import { JSONObject } from "../general.types.js";
export interface PlaylistSimplified extends JSONObject {

@@ -6,0 +6,0 @@ /**

@@ -1,4 +0,5 @@

import { HTTPClient, SearchParams } from "@soundify/shared";
import { SearchParams } from "@soundify/shared";
import { Market } from "../market/market.types.js";
import { SearchFilters, SearchResponse, SearchType, SearchTypeLiteral } from "./search.types.js";
import { HTTPClient } from "../client.js";
export interface SearchOpts extends SearchParams {

@@ -5,0 +6,0 @@ /**

@@ -6,3 +6,4 @@ import { PagingObject } from "../general.types.js";

import { PlaylistSimplified } from "../playlist/playlist.types.js";
import { JSONObject, SearchParams } from "@soundify/shared";
import { SearchParams } from "@soundify/shared";
import { JSONObject } from "../general.types.js";
/**

@@ -9,0 +10,0 @@ * Item types to search across.

@@ -1,2 +0,2 @@

import { HTTPClient } from "@soundify/shared";
import { HTTPClient } from "../client.js";
import { Market } from "../market/market.types.js";

@@ -3,0 +3,0 @@ import { PagingObject, PagingOptions } from "../general.types.js";

@@ -1,2 +0,2 @@

import { JSONObject, SearchParams } from "@soundify/shared";
import { SearchParams } from "@soundify/shared";
import { AlbumSimplified } from "../album/album.types.js";

@@ -7,3 +7,3 @@ import { Artist } from "../artist/artist.types.js";

import { ArtistSimplified } from "../artist/artist.types.js";
import { ExternalIds, ExternalUrls, RestrictionsReason } from "../general.types.js";
import { ExternalIds, ExternalUrls, JSONObject, RestrictionsReason } from "../general.types.js";
export interface LinkedTrack extends JSONObject {

@@ -10,0 +10,0 @@ /**

@@ -5,3 +5,4 @@ import { Artist } from "../artist/artist.types.js";

import { CursorPagingObject, PagingObject, PagingOptions } from "../general.types.js";
import { HTTPClient, SearchParams } from "@soundify/shared";
import { SearchParams } from "@soundify/shared";
import { HTTPClient } from "../client.js";
/**

@@ -13,3 +14,3 @@ * Get detailed profile information about the current user.

export declare const getCurrentUser: (client: HTTPClient) => Promise<UserPrivate>;
interface GetUserTopItemsOpts extends SearchParams, PagingOptions {
export type GetUserTopItemsOpts = {
/**

@@ -25,3 +26,3 @@ * Over what time frame the affinities are computed.

time_range?: "long_term" | "medium_term" | "short_term";
}
} & PagingOptions;
type TopItemType = "artists" | "tracks";

@@ -37,2 +38,4 @@ type TopItem = Artist | Track;

*
* @requires `user-top-read`
*
* @param client Spotify HTTPClient

@@ -46,2 +49,4 @@ * @param type The type of entity to return. ("artists" or "tracks")

*
* @requires `user-top-read`
*
* @param client Spotify HTTPClient

@@ -54,2 +59,4 @@ * @param opts Additional option for request

*
* @requires `user-top-read`
*
* @param client Spotify HTTPClient

@@ -69,2 +76,4 @@ * @param opts Additional option for request

*
* @requires `playlist-modify-public` or `playlist-modify-private`
*
* @param client Spotify HTTPClient

@@ -79,2 +88,4 @@ * @param playlist_id Spotify playlist ID

*
* @requires `playlist-modify-public` or `playlist-modify-private`
*
* @param client Spotify HTTPClient

@@ -93,2 +104,4 @@ * @param playlist_id Spotify playlist ID

*
* @requires `user-follow-read`
*
* @param client Spotify HTTPClient

@@ -101,2 +114,4 @@ * @param opts Additional option for request

*
* @requires `user-follow-modify`
*
* @param client Spotify HTTPClient

@@ -109,2 +124,4 @@ * @param artist_ids List of Spotify artist IDs. Maximum 50

*
* @requires `user-follow-modify`
*
* @param client Spotify HTTPClient

@@ -117,2 +134,4 @@ * @param artist_id Spotify artist ID

*
* @requires `user-follow-modify`
*
* @param client Spotify HTTPClient

@@ -125,2 +144,4 @@ * @param artist_ids List of Spotify user IDs. Maximum 50

*
* @requires `user-follow-modify`
*
* @param client Spotify HTTPClient

@@ -133,2 +154,4 @@ * @param artist_id Spotify user ID

*
* @requires `user-follow-modify`
*
* @param client Spotify HTTPClient

@@ -141,2 +164,4 @@ * @param artist_ids List of Spotify artist IDs. Maximum 50

*
* @requires `user-follow-modify`
*
* @param client Spotify HTTPClient

@@ -149,2 +174,4 @@ * @param artist_id Spotify artist ID

*
* @requires `user-follow-modify`
*
* @param client Spotify HTTPClient

@@ -157,2 +184,4 @@ * @param user_ids List of Spotify user IDs. Maximum 50

*
* @requires `user-follow-modify`
*
* @param client Spotify HTTPClient

@@ -165,2 +194,4 @@ * @param artist_id Spotify user ID

*
* @requires `user-follow-read`
*
* @param client Spotify HTTPClient

@@ -173,2 +204,4 @@ * @param artist_ids List of Spotify artist IDs. Maximum 50

*
* @requires `user-follow-read`
*
* @param client Spotify HTTPClient

@@ -181,2 +214,4 @@ * @param artist_id Spotify artist ID

*
* @requires `user-follow-read`
*
* @param client Spotify HTTPClient

@@ -189,2 +224,4 @@ * @param user_ids List of Spotify user IDs. Maximum 50

*
* @requires `user-follow-read`
*
* @param client Spotify HTTPClient

@@ -191,0 +228,0 @@ * @param user_id Spotify user ID

@@ -1,3 +0,5 @@

import { JSONObject } from "@soundify/shared";
import { type ExternalUrls, type Followers, type Image } from "../general.types.js";
import { type ExternalUrls, type Followers, type Image, JSONObject } from "../general.types.js";
/**
* The spotify api object containing details of a user's public details.
*/
export interface UserPublic extends JSONObject {

@@ -56,3 +58,8 @@ /**

}
export interface UserPrivate extends UserPublic, JSONObject {
/**
* The spotify api object containing details of a user's public and private details.
*
* For complete information, you might consider including scopes: `user-read-private`, `user-read-email`.
*/
export interface UserPrivate extends UserPublic {
/**

@@ -64,3 +71,3 @@ * The country of the user, as set in the user's account profile.

*/
country: string;
country?: string;
/**

@@ -75,3 +82,3 @@ * The user's email address, as entered by the user when creating

*/
email: string;
email?: string;
/**

@@ -78,0 +85,0 @@ * The user's explicit content settings.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc