import superjson from "superjson"; import { appendSetCookies, ensureSpotifyAccessToken } from "../helpers/spotifyServer"; import type { OutputType, SpotifyPlaylistSummary } from "./spotify-playlists_GET.schema"; type SpotifyPlaylistPage = { items?: Array<{ id?: string; name?: string; owner?: { display_name?: string; id?: string }; collaborative?: boolean; images?: Array<{ url?: string }>; external_urls?: { spotify?: string }; items?: { total?: number }; tracks?: { total?: number }; }>; next?: string | null; }; async function spotifyGet(url: string, accessToken: string) { const response = await fetch(url, { headers: { Authorization: `Bearer ${accessToken}` }, }); if (!response.ok) { const message = await response.text(); throw new Error(`Spotify returned ${response.status}: ${message.slice(0, 220)}`); } return (await response.json()) as T; } export async function handle(request: Request) { try { const session = await ensureSpotifyAccessToken(request); if (!session.accessToken) { return new Response(superjson.stringify({ error: "Connect Spotify first." }), { status: 401 }); } let next: string | null = "https://api.spotify.com/v1/me/playlists?limit=50"; const playlists: SpotifyPlaylistSummary[] = []; while (next) { const page: SpotifyPlaylistPage = await spotifyGet(next, session.accessToken); for (const playlist of page.items ?? []) { if (!playlist.id) continue; playlists.push({ id: playlist.id, name: playlist.name || "Untitled playlist", owner: playlist.owner?.display_name || playlist.owner?.id, ownerId: playlist.owner?.id, collaborative: Boolean(playlist.collaborative), imageUrl: playlist.images?.find((image) => image.url)?.url, total: playlist.items?.total ?? playlist.tracks?.total ?? 0, externalUrl: playlist.external_urls?.spotify, }); } next = page.next || null; } const headers = new Headers({ "Content-Type": "application/json", "Cache-Control": "no-store" }); appendSetCookies(headers, session.setCookies); return new Response(superjson.stringify({ playlists } satisfies OutputType), { headers }); } catch (error) { const message = error instanceof Error ? error.message : "Unable to list Spotify playlists."; return new Response(superjson.stringify({ error: message }), { status: 500 }); } }