Personal Site

Skip unused "item" field in spotify api

vielle.dev d5d60bb7 f01e3563

verified
+42 -26
+26 -6
src/components/playing/spotify/api.ts
··· 1 import getAccessCode from "./access"; 2 import { SpotifyError, throws } from "./errors"; 3 import { isNowPlaying, type nowPlaying } from "./types"; 4 5 /** 6 * Wrapper for authorizing a spotify API with default headers etc ··· 33 * @throws `SpotifyError` of NO_AUTH | UNHANDLED_API_ERR | INVALID_AUTH_RES | RATE_LIMITED | NO_CONTENT | MALFORMED_SPOTIFY_RES 34 */ 35 export async function spotifyNowPlaying() { 36 - type success = nowPlaying["item"]; 37 let res: (v: success) => void, rej: (v: unknown) => void; 38 const output = new Promise<success>((_res, _rej) => { 39 (res = _res), (rej = _rej); ··· 138 // quit early if it rejected last time 139 if (!resp) return; 140 try { 141 - const json = await resp.json(); 142 - 143 144 // verify structure 145 if (!isNowPlaying(json)) { 146 - rej(new SpotifyError("MALFORMED_SPOTIFY_RES", json, "Response missing required fields.")); 147 return; 148 } 149 150 - res(json.item) 151 - } catch (e) {} 152 }); 153 154 return output;
··· 1 import getAccessCode from "./access"; 2 import { SpotifyError, throws } from "./errors"; 3 import { isNowPlaying, type nowPlaying } from "./types"; 4 + import { isObj } from "/utils"; 5 6 /** 7 * Wrapper for authorizing a spotify API with default headers etc ··· 34 * @throws `SpotifyError` of NO_AUTH | UNHANDLED_API_ERR | INVALID_AUTH_RES | RATE_LIMITED | NO_CONTENT | MALFORMED_SPOTIFY_RES 35 */ 36 export async function spotifyNowPlaying() { 37 + type success = nowPlaying; 38 let res: (v: success) => void, rej: (v: unknown) => void; 39 const output = new Promise<success>((_res, _rej) => { 40 (res = _res), (rej = _rej); ··· 139 // quit early if it rejected last time 140 if (!resp) return; 141 try { 142 + const json = await resp 143 + .json() 144 + .then((res) => 145 + isObj(res) && "item" in res && isObj(res.item) 146 + ? res.item 147 + : throws("Item field missing"), 148 + ); 149 150 // verify structure 151 if (!isNowPlaying(json)) { 152 + rej( 153 + new SpotifyError( 154 + "MALFORMED_SPOTIFY_RES", 155 + json, 156 + "Response missing required fields.", 157 + ), 158 + ); 159 return; 160 } 161 162 + res(json); 163 + } catch (e) { 164 + rej( 165 + new SpotifyError( 166 + "MALFORMED_SPOTIFY_RES", 167 + e, 168 + "Could not parse JSON.", 169 + ), 170 + ); 171 + } 172 }); 173 174 return output;
+16 -20
src/components/playing/spotify/types.ts
··· 37 return isRefreshToken(obj) && "refresh_token" in obj; 38 } 39 40 - export type nowPlaying = { 41 - item: null | { 42 type: "track"; 43 id: string; 44 name: string; ··· 54 id: string; 55 }[]; 56 }; 57 - }; 58 59 - export function isNowPlaying(obj: object): obj is nowPlaying { 60 return ( 61 isObj(obj) && 62 - "item" in obj && 63 - isObj(obj.item) && 64 - "type" in obj.item && 65 - obj.item.type === "track" && 66 - "id" in obj.item && 67 - typeof obj.item.id === "string" && 68 - "name" in obj.item && 69 - typeof obj.item.name === "string" && 70 - "album" in obj.item && 71 - isObj(obj.item.album) && 72 - "images" in obj.item.album && 73 - Array.isArray(obj.item.album.images) && 74 - obj.item.album.images.reduce( 75 (acc, curr) => 76 acc && 77 "url" in curr && ··· 82 typeof curr.width === "number", 83 true, 84 ) && 85 - "artists" in obj.item && 86 - Array.isArray(obj.item.artists) && 87 - obj.item.artists.reduce( 88 (acc, curr) => 89 acc && 90 "name" in curr &&
··· 37 return isRefreshToken(obj) && "refresh_token" in obj; 38 } 39 40 + export type nowPlaying =null | { 41 type: "track"; 42 id: string; 43 name: string; ··· 53 id: string; 54 }[]; 55 }; 56 57 + export function isNowPlaying(obj: unknown): obj is nowPlaying { 58 return ( 59 isObj(obj) && 60 + "type" in obj && 61 + obj.type === "track" && 62 + "id" in obj && 63 + typeof obj.id === "string" && 64 + "name" in obj && 65 + typeof obj.name === "string" && 66 + "album" in obj && 67 + isObj(obj.album) && 68 + "images" in obj.album && 69 + Array.isArray(obj.album.images) && 70 + obj.album.images.reduce( 71 (acc, curr) => 72 acc && 73 "url" in curr && ··· 78 typeof curr.width === "number", 79 true, 80 ) && 81 + "artists" in obj && 82 + Array.isArray(obj.artists) && 83 + obj.artists.reduce( 84 (acc, curr) => 85 acc && 86 "name" in curr &&