Skip to content

Commit

Permalink
fix: handle not json reponse body and update examples
Browse files Browse the repository at this point in the history
  • Loading branch information
MellKam committed Feb 24, 2023
1 parent 20bf9c1 commit 0a486d3
Show file tree
Hide file tree
Showing 36 changed files with 286 additions and 177 deletions.
4 changes: 3 additions & 1 deletion api/shared/paging.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { QueryParams } from "../../utils.ts";

export interface PagingObject<T> {
href: string;
items: T[];
Expand All @@ -17,7 +19,7 @@ export interface CursorPagingObject<T> {
total: number;
}

export interface PagingOptions extends Record<string, number | undefined> {
export interface PagingOptions extends QueryParams {
/**
* The maximum number of items to return. Default: 20. Minimum: 1. Maximum: 50.
*/
Expand Down
16 changes: 10 additions & 6 deletions api/user/user.endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Track } from "../track/track.types.ts";
import { UserPrivate, UserPublic } from "./user.types.ts";
import { PagingObject, PagingOptions } from "../shared/index.ts";
import { ISpotifyClient } from "../../client.ts";
import { QueryParams } from "../../utils.ts";

/**
* Get detailed profile information about the current user
Expand All @@ -12,9 +13,9 @@ export const getCurrentUserProfile = (spotifyClient: ISpotifyClient) => {
return spotifyClient.fetch<UserPrivate>("/me");
};

type GetUserTopItemsOpts = PagingOptions & {
interface GetUserTopItemsOpts extends QueryParams {
time_range?: "long_term" | "medium_term" | "short_term";
};
}

type TopItemType = "artists" | "tracks";
type TopItem = Artist | Track;
Expand All @@ -32,11 +33,14 @@ export const getUserTopItems = <
>(
spotifyClient: ISpotifyClient,
type: T,
query: GetUserTopItemsOpts,
query?: GetUserTopItemsOpts & PagingOptions,
) => {
return spotifyClient.fetch<PagingObject<M[T]>>(`/me/top/${type}`, {
query,
});
return spotifyClient.fetch<PagingObject<M[T]>>(
`/me/top/${type}`,
{
query,
},
);
};

/**
Expand Down
25 changes: 17 additions & 8 deletions client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IAuthProvider } from "./auth/types.ts";
import { searchParamsFromObj } from "./utils.ts";
import { QueryParams, searchParamsFromObj } from "./utils.ts";

export const API_PREFIX = "https://api.spotify.com/v1";

Expand Down Expand Up @@ -29,7 +29,7 @@ export interface ISpotifyClient {
>(baseURL: string, opts?: {
method?: HTTPMethod;
body?: Record<string, unknown>;
query?: Record<string, string | number | boolean | undefined>;
query?: QueryParams;
}) => Promise<R>;
}

Expand All @@ -50,7 +50,7 @@ export class SpotifyClient implements ISpotifyClient {
{ body, query, method }: {
method?: HTTPMethod;
body?: Record<string, unknown>;
query?: Record<string, string | number | boolean | undefined>;
query?: QueryParams;
} = {},
) => {
const url = new URL(API_PREFIX + baseURL);
Expand All @@ -74,20 +74,29 @@ export class SpotifyClient implements ISpotifyClient {
});

if (!res.ok) {
const { error: { message, status } } = await res
.json() as SpotifyRawError;
let error: SpotifyRawError;
try {
error = await res.json() as SpotifyRawError;
} catch (_) {
throw new SpotifyError(
"Unable to read response body(not a json value)",
res.status,
);
}

const { error: { message } } = error;
if (
typeof this.#authProvider !== "string" && status === 401 && !authRetry
res.status === 401 && typeof this.#authProvider !== "string" &&
!authRetry
) {
const access_token = await this.#authProvider.getAccessToken(
true,
);
authRetry = true;
return await call(access_token);
} else {
throw new SpotifyError(message, status);
}

throw new SpotifyError(message, res.status);
}

return res;
Expand Down
2 changes: 2 additions & 0 deletions examples/deno-oak-auth/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<img width="360" alt="Soundify example banner" src="https://user-images.githubusercontent.com/51422045/221211970-06ef3ffc-20b2-4bfb-a468-92e92a84ed22.png">

# Soundify exapmle (deno-oak-auth)

This example uses [OAK](https://github.com/oakserver/oak) (deno http framework)
Expand Down
12 changes: 0 additions & 12 deletions examples/deno-oak-auth/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,9 @@ import { AuthCode } from "../../mod.ts";

const PORT = 3000;

/**
* You can create your app and get all the secrets here
* Spoity Dashboard - `https://developer.spotify.com/dashboard`
*/
const env = cleanEnv(config(), {
SPOTIFY_CLIENT_ID: str(),
SPOTIFY_CLIENT_SECRET: str(),
/**
* Make sure that in the dashboard of your Spotify app,
* in Settings -> Redirect URIs, this link is specified:
*
* @link `http://localhost:${PORT}/callback`
*
* @var PORT - variable that exists above. By default it is `3000`
*/
SPOTIFY_REDIRECT_URI: url(),
});

Expand Down
5 changes: 5 additions & 0 deletions examples/next-ssr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<img width="360px" alt="Soundify example banner" src="https://user-images.githubusercontent.com/51422045/221219632-d89c4d89-05ca-4927-8419-af81cfd38875.png" />

# Soundify exapmle (next-ssr)

// TODO
5 changes: 5 additions & 0 deletions examples/node-express-auth/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<img width="360px" alt="Soundify example banner" src="https://user-images.githubusercontent.com/51422045/221220147-a45333a1-be36-44b1-b06e-e9d6153518c8.png" />

# Soundify exapmle (node-express-auth)

// TODO
4 changes: 2 additions & 2 deletions examples/node-express-auth/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ app.get("/callback", async (req, res) => {
}

try {
const keypairData = await AuthCode.getGrantData({
const grantData = await AuthCode.getGrantData({
code,
state,
...config,
});

res.status(200).json(keypairData);
res.status(200).json(grantData);
} catch (error) {
res.status(400).send(String(error));
}
Expand Down
53 changes: 0 additions & 53 deletions examples/pkce-auth/src/pages/callback.tsx

This file was deleted.

29 changes: 0 additions & 29 deletions examples/pkce-auth/src/pages/index.tsx

This file was deleted.

50 changes: 0 additions & 50 deletions examples/pkce-auth/src/spotify.ts

This file was deleted.

File renamed without changes.
5 changes: 5 additions & 0 deletions examples/react-implicit-grant/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<img width="360" alt="Soundify example banner" src="https://user-images.githubusercontent.com/51422045/221219257-bac1fa98-3bb1-4497-8c96-08dd5e40370f.png">

# Soundify exapmle (react-implicit-grant)

// TODO
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@examples/react-vite",
"name": "@examples/react-implicit-grant",
"private": "true",
"type": "module",
"scripts": {
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { ImplicitGrant } from "soundify-web-api/web";
import { SPOTIFY_ACCESS_TOKEN } from "../spotify";

export const Page = () => {
const { access_token } = ImplicitGrant.getGrantData(location.hash);
localStorage.setItem(SPOTIFY_ACCESS_TOKEN, access_token);
localStorage.setItem("SPOTIFY_ACCESS_TOKEN", access_token);

location.replace("/");
return <h1>Redirecting...</h1>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ import { useQuery } from "@tanstack/react-query";
import {
getCurrentUserProfile,
ImplicitGrant,
PureAuthProvider,
SpotifyClient,
} from "soundify-web-api/web";
import { SPOTIFY_ACCESS_TOKEN } from "../spotify";

const useSpotifyClient = () => {
const accessToken = localStorage.getItem(SPOTIFY_ACCESS_TOKEN);
const accessToken = localStorage.getItem("SPOTIFY_ACCESS_TOKEN");

if (!accessToken) {
location.replace(ImplicitGrant.getAuthURL({
Expand All @@ -19,7 +17,7 @@ const useSpotifyClient = () => {
}

return new SpotifyClient({
authProvider: new PureAuthProvider(accessToken!),
authProvider: accessToken!,
});
};

Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions examples/react-pkce-auth/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VITE_SPOTIFY_CLIENT_ID=
VITE_SPOTIFY_REDIRECT_URI=http://localhost:3000/callback
12 changes: 12 additions & 0 deletions examples/react-pkce-auth/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<img width="360" alt="Soundify example banner" src="https://user-images.githubusercontent.com/51422045/221218925-6fcfa2d0-d7fe-4dd8-983a-c9f6efe1dc36.png">

# Soundify exapmle (react-pkce-auth)

This example shows how to use PKCE authentication in a single-page React application. We will also use the `react-router-dom`, `@tanstack/react-query` libraries to speed up our routine workflow.

Don't forget to fill in the env variables in the `.env` file in the same way as
in the `.env.example` file.

After logging to your spotify you will see your top artists

<img src="https://user-images.githubusercontent.com/51422045/221215586-13f60468-d1a6-4810-b33e-e12471d77c01.jpg">
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@examples/pkce-auth",
"name": "@examples/react-pkce-auth",
"private": "true",
"type": "module",
"scripts": {
Expand Down
File renamed without changes.
Loading

0 comments on commit 0a486d3

Please sign in to comment.