- Spotify playlist, library, album and artist browsing with in-app playback - Song, playlist and album downloads via spotdl with YouTube and Bandcamp fallbacks - Electron desktop app (castLabs Widevine) with a permanent sidebar layout - Linux and Windows packaging scripts
42 lines
1.1 KiB
TypeScript
42 lines
1.1 KiB
TypeScript
import { z } from "zod";
|
|
import superjson from "superjson";
|
|
|
|
export const schema = z.object({
|
|
title: z.string().min(1),
|
|
artist: z.string().min(1),
|
|
album: z.string().optional(),
|
|
isrc: z.string().optional(),
|
|
durationMs: z.number().nonnegative().optional(),
|
|
});
|
|
|
|
export type InputType = z.infer<typeof schema>;
|
|
|
|
export type OutputType = {
|
|
isrc?: string;
|
|
releaseDate?: string;
|
|
genre?: string;
|
|
composer?: string;
|
|
albumArtist?: string;
|
|
artworkUrl?: string;
|
|
lyrics?: {
|
|
plain?: string;
|
|
synced?: string;
|
|
};
|
|
musicBrainzRecordingId?: string;
|
|
sources: string[];
|
|
};
|
|
|
|
export async function postMetadataEnrich(body: InputType): Promise<OutputType> {
|
|
const validated = schema.parse(body);
|
|
const response = await fetch("/_api/metadata-enrich", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: superjson.stringify(validated),
|
|
});
|
|
if (!response.ok) {
|
|
const parsed = superjson.parse<{ error: string }>(await response.text());
|
|
throw new Error(parsed.error);
|
|
}
|
|
return superjson.parse<OutputType>(await response.text());
|
|
}
|