add native nd radio endpoints, support radio station images

This commit is contained in:
jeffvli
2026-04-02 18:26:26 -07:00
parent fbf82c1ef0
commit db06e7f601
18 changed files with 789 additions and 90 deletions
@@ -8,6 +8,7 @@ import {
AlbumArtist,
ExplicitStatus,
Genre,
InternetRadioStation,
LibraryItem,
Playlist,
RelatedArtist,
@@ -543,10 +544,28 @@ const normalizeUser = (item: z.infer<typeof ndType._response.user>): User => {
};
};
const normalizeInternetRadioStation = (
item: z.infer<typeof ndType._response.radioStation>,
): InternetRadioStation => {
const homepageUrl = item.homePageUrl?.trim() ? item.homePageUrl : null;
const imageId = item.uploadedImage ? `ra-${item.id}&square=true&_=${item.updatedAt}` : item.id;
return {
homepageUrl,
id: item.id,
imageId,
imageUrl: null,
name: item.name,
streamUrl: item.streamUrl,
uploadedImage: item.uploadedImage || null,
};
};
export const ndNormalize = {
album: normalizeAlbum,
albumArtist: normalizeAlbumArtist,
genre: normalizeGenre,
internetRadioStation: normalizeInternetRadioStation,
playlist: normalizePlaylist,
song: normalizeSong,
user: normalizeUser,
@@ -660,6 +660,12 @@ const updatePlaylist = playlist;
const updatePlaylistParameters = createPlaylistParameters.partial();
const updateInternetRadioStationParameters = z.object({
homePageUrl: z.string().optional(),
name: z.string(),
streamUrl: z.string(),
});
const uploadPlaylistImage = z.object({
status: z.string(),
});
@@ -672,8 +678,14 @@ const deletePlaylistImage = z.object({
status: z.string(),
});
const uploadInternetRadioStationImage = uploadPlaylistImage;
const uploadInternetRadioStationImageParameters = uploadPlaylistImageParameters;
const deleteInternetRadioStationImage = deletePlaylistImage;
const deletePlaylist = z.null();
const deleteInternetRadioStation = deletePlaylist;
const addToPlaylist = z.object({
added: z.number(),
});
@@ -748,12 +760,35 @@ const queue = z.object({
userId: z.string(),
});
export enum NDRadioListSort {
NAME = 'name',
}
const radioStation = z.object({
createdAt: z.string(),
homePageUrl: z.string().optional(),
id: z.string(),
name: z.string(),
streamUrl: z.string(),
updatedAt: z.string(),
uploadedImage: z.string().optional(),
});
const radioList = z.array(radioStation);
const updateInternetRadioStation = radioStation;
const radioListParameters = optionalPaginationParameters.extend({
_sort: z.nativeEnum(NDRadioListSort).optional(),
});
export const ndType = {
_enum: {
albumArtistList: NDAlbumArtistListSort,
albumList: NDAlbumListSort,
genreList: genreListSort,
playlistList: NDPlaylistListSort,
radioList: NDRadioListSort,
songList: NDSongListSort,
tagList: NDTagListSort,
userList: ndUserListSort,
@@ -767,12 +802,15 @@ export const ndType = {
genreList: genreListParameters,
moveItem: moveItemParameters,
playlistList: playlistListParameters,
radioList: radioListParameters,
removeFromPlaylist: removeFromPlaylistParameters,
saveQueue: saveQueueParameters,
shareItem: shareItemParameters,
songList: songListParameters,
tagList: tagListParameters,
updateInternetRadioStation: updateInternetRadioStationParameters,
updatePlaylist: updatePlaylistParameters,
uploadInternetRadioStationImage: uploadInternetRadioStationImageParameters,
uploadPlaylistImage: uploadPlaylistImageParameters,
userList: userListParameters,
},
@@ -784,6 +822,8 @@ export const ndType = {
albumList,
authenticate,
createPlaylist,
deleteInternetRadioStation,
deleteInternetRadioStationImage,
deletePlaylist,
deletePlaylistImage,
error,
@@ -795,13 +835,17 @@ export const ndType = {
playlistSong,
playlistSongList,
queue,
radioList,
radioStation,
removeFromPlaylist,
saveQueue,
shareItem,
song,
songList,
tagList,
updateInternetRadioStation,
updatePlaylist,
uploadInternetRadioStationImage,
uploadPlaylistImage,
user,
userList,
@@ -432,6 +432,8 @@ const normalizeInternetRadioStation = (
return {
homepageUrl: item.homepageUrl || null,
id: item.id,
imageId: item.coverArt?.toString() || null,
imageUrl: null,
name: item.name,
streamUrl: item.streamUrl,
};
@@ -755,6 +755,7 @@ const playQueueByIndex = z.object({
});
const internetRadioStation = z.object({
coverArt: z.string().optional(),
homepageUrl: z.string().optional(),
id: z.string(),
name: z.string(),