Files
Aurora-SpotiRip/endpoints/identify_POST.schema.ts
R3ap3r 3178b8f4f7 Aurora SpotiRip desktop and web app
- 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
2026-09-25 23:20:57 -05:00

55 lines
1.5 KiB
TypeScript

import { z } from "zod";
import superjson from "superjson";
export const MAX_AUDIO_BYTES = 4 * 1024 * 1024;
export const schema = z.object({
file: z
.custom<File>((value) => typeof File !== "undefined" && value instanceof File, "Audio file is required")
.refine((file) => file.size > 0, "Audio file is empty")
.refine((file) => file.size <= MAX_AUDIO_BYTES, "Audio file exceeds the 80 MB limit")
.refine(
(file) =>
file.type === "audio/mpeg" ||
file.type === "audio/wav" ||
file.type === "audio/x-wav" ||
file.name.toLowerCase().endsWith(".mp3") ||
file.name.toLowerCase().endsWith(".wav"),
"Recognition snippet must be MP3 or WAV",
),
});
export type OutputType = {
matched: boolean;
title?: string;
artist?: string;
album?: string;
releaseDate?: string;
label?: string;
timecode?: string;
songLink?: string;
artworkUrl?: string;
spotifyUri?: string;
spotifyUrl?: string;
trackNumber?: number;
discNumber?: number;
isrc?: string;
};
export async function postIdentify(file: File, init?: RequestInit): Promise<OutputType> {
const form = new FormData();
form.append("file", file, file.name);
const result = await fetch("/_api/identify", {
method: "POST",
body: form,
...init,
});
if (!result.ok) {
const errorObject = superjson.parse<{ error: string }>(await result.text());
throw new Error(errorObject.error);
}
return superjson.parse<OutputType>(await result.text());
}