search.ts•2.73 kB
import type { SpotifyClient } from "../spotify-client.js";
import type { SearchResponse } from "../types.js";
export interface SearchParams {
query: string;
types: string[];
limit?: number;
}
export async function searchSpotify(
client: SpotifyClient,
params: SearchParams
): Promise<SearchResponse> {
const { query, types, limit = 10 } = params;
// Validate types
const validTypes = ["track", "album", "artist"];
const invalidTypes = types.filter((t) => !validTypes.includes(t));
if (invalidTypes.length > 0) {
throw new Error(
`Invalid search types: ${invalidTypes.join(", ")}. Valid types are: ${validTypes.join(", ")}`
);
}
// Make API request
const response = await client.get<SearchResponse>("/search", {
q: query,
type: types.join(","),
limit,
});
return response;
}
/**
* Format search results for display
*/
export function formatSearchResults(results: SearchResponse): string {
const sections: string[] = [];
// Format tracks
if (results.tracks?.items && results.tracks.items.length > 0) {
sections.push("**Tracks:**");
results.tracks.items.forEach((track, i) => {
const artists = track.artists.map((a) => a.name).join(", ");
sections.push(
`${i + 1}. "${track.name}" by ${artists} (Album: ${track.album.name})`
);
sections.push(` URI: ${track.uri}`);
sections.push(` Duration: ${formatDuration(track.duration_ms)}`);
});
sections.push("");
}
// Format artists
if (results.artists?.items && results.artists.items.length > 0) {
sections.push("**Artists:**");
results.artists.items.forEach((artist, i) => {
sections.push(`${i + 1}. ${artist.name}`);
sections.push(` URI: ${artist.uri}`);
sections.push(` Spotify: ${artist.external_urls.spotify}`);
});
sections.push("");
}
// Format albums
if (results.albums?.items && results.albums.items.length > 0) {
sections.push("**Albums:**");
results.albums.items.forEach((album, i) => {
const artists = album.artists.map((a) => a.name).join(", ");
sections.push(
`${i + 1}. "${album.name}" by ${artists} (${album.release_date})`
);
sections.push(` URI: ${album.uri}`);
sections.push(` Tracks: ${album.total_tracks}`);
});
sections.push("");
}
if (sections.length === 0) {
return "No results found.";
}
return sections.join("\n");
}
/**
* Format duration from milliseconds to MM:SS
*/
function formatDuration(ms: number): string {
const totalSeconds = Math.floor(ms / 1000);
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
return `${minutes}:${seconds.toString().padStart(2, "0")}`;
}