Handle subsonic endpoints that potentially return optional response when no items
This commit is contained in:
parent
0e8b2aed72
commit
c96f5b207d
2 changed files with 64 additions and 50 deletions
|
@ -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, ''),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Reference in a new issue