Handle subsonic endpoints that potentially return optional response when no items

This commit is contained in:
jeffvli 2024-09-26 11:14:06 -07:00
parent 0e8b2aed72
commit c96f5b207d
2 changed files with 64 additions and 50 deletions

View file

@ -270,7 +270,7 @@ export const SubsonicController: ControllerEndpoint = {
} }
const results = const results =
res.body.searchResult3.album?.map((album) => res.body.searchResult3?.album?.map((album) =>
ssNormalize.album(album, apiClientProps.server), ssNormalize.album(album, apiClientProps.server),
) || []; ) || [];
@ -325,14 +325,14 @@ export const SubsonicController: ControllerEndpoint = {
} }
const results = const results =
res.body.starred.album?.map((album) => res.body.starred?.album?.map((album) =>
ssNormalize.album(album, apiClientProps.server), ssNormalize.album(album, apiClientProps.server),
) || []; ) || [];
return { return {
items: sortAlbumList(results, query.sortBy, query.sortOrder), items: sortAlbumList(results, query.sortBy, query.sortOrder),
startIndex: 0, startIndex: 0,
totalRecordCount: res.body.starred.album?.length || 0, totalRecordCount: res.body.starred?.album?.length || 0,
}; };
} }
@ -410,7 +410,7 @@ export const SubsonicController: ControllerEndpoint = {
throw new Error('Failed to get album list count'); throw new Error('Failed to get album list count');
} }
const albumCount = res.body.searchResult3.album?.length; const albumCount = (res.body.searchResult3?.album || [])?.length;
totalRecordCount += albumCount; totalRecordCount += albumCount;
startIndex += albumCount; startIndex += albumCount;
@ -433,7 +433,7 @@ export const SubsonicController: ControllerEndpoint = {
throw new Error('Failed to get album list'); throw new Error('Failed to get album list');
} }
return res.body.starred.album?.length || 0; return (res.body.starred?.album || []).length || 0;
} }
let type = ALBUM_LIST_SORT_MAPPING[query.sortBy] ?? AlbumListSortType.ALPHABETICAL_BY_NAME; let type = ALBUM_LIST_SORT_MAPPING[query.sortBy] ?? AlbumListSortType.ALPHABETICAL_BY_NAME;
@ -523,7 +523,7 @@ export const SubsonicController: ControllerEndpoint = {
throw new Error('Failed to get genre list'); throw new Error('Failed to get genre list');
} }
let results = res.body.genres.genre; let results = res.body.genres?.genre || [];
if (query.searchTerm) { if (query.searchTerm) {
const searchResults = filter(results, (genre) => const searchResults = filter(results, (genre) =>
@ -588,7 +588,7 @@ export const SubsonicController: ControllerEndpoint = {
throw new Error('Failed to get playlist list'); throw new Error('Failed to get playlist list');
} }
let results = res.body.playlists.playlist; let results = res.body.playlists?.playlist || [];
if (query.searchTerm) { if (query.searchTerm) {
const searchResults = filter(results, (playlist) => { const searchResults = filter(results, (playlist) => {
@ -634,7 +634,7 @@ export const SubsonicController: ControllerEndpoint = {
throw new Error('Failed to get playlist list'); throw new Error('Failed to get playlist list');
} }
let results = res.body.playlists.playlist; let results = res.body.playlists?.playlist || [];
if (query.searchTerm) { if (query.searchTerm) {
const searchResults = filter(results, (playlist) => { const searchResults = filter(results, (playlist) => {
@ -689,10 +689,10 @@ export const SubsonicController: ControllerEndpoint = {
throw new Error('Failed to get random songs'); throw new Error('Failed to get random songs');
} }
const results = res.body.randomSongs?.song || [];
return { return {
items: res.body.randomSongs?.song?.map((song) => items: results.map((song) => ssNormalize.song(song, apiClientProps.server, '')),
ssNormalize.song(song, apiClientProps.server, ''),
),
startIndex: 0, startIndex: 0,
totalRecordCount: res.body.randomSongs?.song?.length || 0, totalRecordCount: res.body.randomSongs?.song?.length || 0,
}; };
@ -818,11 +818,11 @@ export const SubsonicController: ControllerEndpoint = {
throw new Error('Failed to get song list'); throw new Error('Failed to get song list');
} }
const results = res.body.songsByGenre?.song || [];
return { return {
items: items:
res.body.songsByGenre.song?.map((song) => results.map((song) => ssNormalize.song(song, apiClientProps.server, '')) || [],
ssNormalize.song(song, apiClientProps.server, ''),
) || [],
startIndex: 0, startIndex: 0,
totalRecordCount: null, totalRecordCount: null,
}; };
@ -840,14 +840,14 @@ export const SubsonicController: ControllerEndpoint = {
} }
const results = const results =
res.body.starred.song?.map((song) => (res.body.starred?.song || []).map((song) =>
ssNormalize.song(song, apiClientProps.server, ''), ssNormalize.song(song, apiClientProps.server, ''),
) || []; ) || [];
return { return {
items: sortSongList(results, query.sortBy, query.sortOrder), items: sortSongList(results, query.sortBy, query.sortOrder),
startIndex: 0, startIndex: 0,
totalRecordCount: res.body.starred.song?.length || 0, totalRecordCount: (res.body.starred?.song || []).length || 0,
}; };
} }
@ -973,7 +973,7 @@ export const SubsonicController: ControllerEndpoint = {
throw new Error('Failed to get song list count'); throw new Error('Failed to get song list count');
} }
const songCount = res.body.searchResult3.song?.length || 0; const songCount = (res.body.searchResult3?.song || []).length || 0;
totalRecordCount += songCount; totalRecordCount += songCount;
startIndex += songCount; startIndex += songCount;
@ -1001,7 +1001,7 @@ export const SubsonicController: ControllerEndpoint = {
throw new Error('Failed to get song list count'); throw new Error('Failed to get song list count');
} }
const numberOfResults = res.body.songsByGenre.song?.length || 0; const numberOfResults = (res.body.songsByGenre?.song || []).length || 0;
if (numberOfResults !== 1) { if (numberOfResults !== 1) {
fetchNextSection = false; fetchNextSection = false;
@ -1026,7 +1026,7 @@ export const SubsonicController: ControllerEndpoint = {
throw new Error('Failed to get song list count'); throw new Error('Failed to get song list count');
} }
const numberOfResults = res.body.songsByGenre.song?.length || 0; const numberOfResults = (res.body.songsByGenre?.song || []).length || 0;
totalRecordCount = startIndex + numberOfResults; totalRecordCount = startIndex + numberOfResults;
startIndex += numberOfResults; startIndex += numberOfResults;
@ -1048,7 +1048,7 @@ export const SubsonicController: ControllerEndpoint = {
throw new Error('Failed to get song list'); throw new Error('Failed to get song list');
} }
return res.body.starred.song?.length || 0; return (res.body.starred?.song || []).length || 0;
} }
let totalRecordCount = 0; let totalRecordCount = 0;
@ -1070,7 +1070,7 @@ export const SubsonicController: ControllerEndpoint = {
throw new Error('Failed to get song list count'); throw new Error('Failed to get song list count');
} }
const numberOfResults = res.body.searchResult3.song?.length || 0; const numberOfResults = (res.body.searchResult3?.song || []).length || 0;
// Check each batch of 5000 songs to check for data // Check each batch of 5000 songs to check for data
sectionIndex += 5000; sectionIndex += 5000;
@ -1099,7 +1099,7 @@ export const SubsonicController: ControllerEndpoint = {
throw new Error('Failed to get song list count'); throw new Error('Failed to get song list count');
} }
const numberOfResults = res.body.searchResult3.song?.length || 0; const numberOfResults = (res.body.searchResult3?.song || []).length || 0;
totalRecordCount = startIndex + numberOfResults; totalRecordCount = startIndex + numberOfResults;
startIndex += numberOfResults; startIndex += numberOfResults;
@ -1237,13 +1237,13 @@ export const SubsonicController: ControllerEndpoint = {
} }
return { return {
albumArtists: res.body.searchResult3?.artist?.map((artist) => albumArtists: (res.body.searchResult3?.artist || [])?.map((artist) =>
ssNormalize.albumArtist(artist, apiClientProps.server), ssNormalize.albumArtist(artist, apiClientProps.server),
), ),
albums: res.body.searchResult3?.album?.map((album) => albums: (res.body.searchResult3?.album || []).map((album) =>
ssNormalize.album(album, apiClientProps.server), ssNormalize.album(album, apiClientProps.server),
), ),
songs: res.body.searchResult3?.song?.map((song) => songs: (res.body.searchResult3?.song || []).map((song) =>
ssNormalize.song(song, apiClientProps.server, ''), ssNormalize.song(song, apiClientProps.server, ''),
), ),
}; };

View file

@ -190,9 +190,11 @@ const topSongsListParameters = z.object({
}); });
const topSongsList = z.object({ const topSongsList = z.object({
topSongs: z.object({ topSongs: z
song: z.array(song), .object({
}), song: z.array(song),
})
.optional(),
}); });
const scrobbleParameters = z.object({ const scrobbleParameters = z.object({
@ -204,11 +206,13 @@ const scrobbleParameters = z.object({
const scrobble = z.null(); const scrobble = z.null();
const search3 = z.object({ const search3 = z.object({
searchResult3: z.object({ searchResult3: z
album: z.array(album), .object({
artist: z.array(albumArtist), album: z.array(album).optional(),
song: z.array(song), artist: z.array(albumArtist).optional(),
}), song: z.array(song).optional(),
})
.optional(),
}); });
const search3Parameters = z.object({ const search3Parameters = z.object({
@ -231,9 +235,11 @@ const randomSongListParameters = z.object({
}); });
const randomSongList = z.object({ const randomSongList = z.object({
randomSongs: z.object({ randomSongs: z
song: z.array(song), .object({
}), song: z.array(song),
})
.optional(),
}); });
const ping = z.object({ const ping = z.object({
@ -310,11 +316,13 @@ const getStarredParameters = z.object({
}); });
const getStarred = z.object({ const getStarred = z.object({
starred: z.object({ starred: z
album: z.array(albumListEntry), .object({
artist: z.array(artistListEntry), album: z.array(albumListEntry),
song: z.array(song), artist: z.array(artistListEntry),
}), song: z.array(song),
})
.optional(),
}); });
const getSongsByGenreParameters = z.object({ const getSongsByGenreParameters = z.object({
@ -325,9 +333,11 @@ const getSongsByGenreParameters = z.object({
}); });
const getSongsByGenre = z.object({ const getSongsByGenre = z.object({
songsByGenre: z.object({ songsByGenre: z
song: z.array(song), .object({
}), song: z.array(song),
})
.optional(),
}); });
const getAlbumParameters = z.object({ const getAlbumParameters = z.object({
@ -408,9 +418,11 @@ const playlistListEntry = playlist.omit({
}); });
const getPlaylists = z.object({ const getPlaylists = z.object({
playlists: z.object({ playlists: z
playlist: z.array(playlistListEntry), .object({
}), playlist: z.array(playlistListEntry),
})
.optional(),
}); });
const getPlaylistParameters = z.object({ const getPlaylistParameters = z.object({
@ -430,9 +442,11 @@ const genre = z.object({
const getGenresParameters = z.object({}); const getGenresParameters = z.object({});
const getGenres = z.object({ const getGenres = z.object({
genres: z.object({ genres: z
genre: z.array(genre), .object({
}), genre: z.array(genre),
})
.optional(),
}); });
export enum AlbumListSortType { export enum AlbumListSortType {