refactor song path replacement

- path replacement during runtime instead of during API normalization
- fix Navidrome API path not appending libraryPath which caused inconsistency between ND and Subsonic paths
This commit is contained in:
jeffvli
2026-06-19 22:02:12 -07:00
parent 36624350f6
commit 61cc87e0b7
15 changed files with 119 additions and 398 deletions
@@ -531,12 +531,7 @@ export const JellyfinController: InternalControllerEndpoint = {
const albumIdSet = new Set([query.id]);
const songs = songsRes.body.Items.filter((item) => albumIdSet.has(item.AlbumId!));
return jfNormalize.album(
{ ...res.body, Songs: songs },
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
);
return jfNormalize.album({ ...res.body, Songs: songs }, apiClientProps.server);
},
getAlbumList: async (args) => {
const { apiClientProps, query } = args;
@@ -630,14 +625,7 @@ export const JellyfinController: InternalControllerEndpoint = {
throw new Error('Failed to get album radio songs');
}
return res.body.Items.map((song) =>
jfNormalize.song(
song,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
);
return res.body.Items.map((song) => jfNormalize.song(song, apiClientProps.server));
},
getArtistList: async (args) => {
const { apiClientProps, query } = args;
@@ -693,14 +681,7 @@ export const JellyfinController: InternalControllerEndpoint = {
throw new Error('Failed to get artist radio songs');
}
return res.body.Items.map((song) =>
jfNormalize.song(
song,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
);
return res.body.Items.map((song) => jfNormalize.song(song, apiClientProps.server));
},
getDownloadUrl: (args) => {
const { apiClientProps, query } = args;
@@ -870,8 +851,6 @@ export const JellyfinController: InternalControllerEndpoint = {
jfNormalize.song(
item as unknown as z.infer<typeof jfType._response.song>,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
);
@@ -1100,14 +1079,7 @@ export const JellyfinController: InternalControllerEndpoint = {
}
return {
items: res.body.Items.map((item) =>
jfNormalize.song(
item,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
),
items: res.body.Items.map((item) => jfNormalize.song(item, apiClientProps.server)),
startIndex: 0,
totalRecordCount: res.body.TotalRecordCount,
};
@@ -1160,14 +1132,7 @@ export const JellyfinController: InternalControllerEndpoint = {
}
return {
items: res.body.Items.map((item) =>
jfNormalize.song(
item,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
),
items: res.body.Items.map((item) => jfNormalize.song(item, apiClientProps.server)),
startIndex: 0,
totalRecordCount: res.body.Items.length || 0,
};
@@ -1219,14 +1184,7 @@ export const JellyfinController: InternalControllerEndpoint = {
if (res.status === 200 && res.body.Items.length) {
const results = res.body.Items.reduce<Song[]>((acc, song) => {
if (song.Id !== query.songId) {
acc.push(
jfNormalize.song(
song,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
);
acc.push(jfNormalize.song(song, apiClientProps.server));
}
return acc;
@@ -1255,14 +1213,7 @@ export const JellyfinController: InternalControllerEndpoint = {
return mix.body.Items.reduce<Song[]>((acc, song) => {
if (song.Id !== query.songId) {
acc.push(
jfNormalize.song(
song,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
);
acc.push(jfNormalize.song(song, apiClientProps.server));
}
return acc;
@@ -1282,12 +1233,7 @@ export const JellyfinController: InternalControllerEndpoint = {
throw new Error('Failed to get song detail');
}
return jfNormalize.song(
res.body,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
);
return jfNormalize.song(res.body, apiClientProps.server);
},
getSongList: async (args) => {
const { apiClientProps, query } = args;
@@ -1399,14 +1345,7 @@ export const JellyfinController: InternalControllerEndpoint = {
}
return {
items: items.map((item) =>
jfNormalize.song(
item,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
),
items: items.map((item) => jfNormalize.song(item, apiClientProps.server)),
startIndex: query.startIndex,
totalRecordCount,
};
@@ -1538,14 +1477,7 @@ export const JellyfinController: InternalControllerEndpoint = {
throw new Error('Failed to get top song list');
}
const items = res.body.Items.map((item) =>
jfNormalize.song(
item,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
);
const items = res.body.Items.map((item) => jfNormalize.song(item, apiClientProps.server));
if (type === 'personal') {
const sorted = orderBy(
@@ -1647,12 +1579,7 @@ export const JellyfinController: InternalControllerEndpoint = {
}
const existingSongs = existingSongsRes.body.Items.map((item) =>
jfNormalize.song(
item,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
jfNormalize.song(item, apiClientProps.server),
);
// 2. Get playlist detail to get the name
@@ -1903,14 +1830,7 @@ export const JellyfinController: InternalControllerEndpoint = {
jfNormalize.albumArtist(item, apiClientProps.server),
),
albums: albums.map((item) => jfNormalize.album(item, apiClientProps.server)),
songs: songs.map((item) =>
jfNormalize.song(
item,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
),
songs: songs.map((item) => jfNormalize.song(item, apiClientProps.server)),
};
},
setPlaylistSongs: async (args) => {
@@ -367,7 +367,7 @@ export const NavidromeController: InternalControllerEndpoint = {
query: { ...query, limit: 1, startIndex: 0 },
}).then((result) => result!.totalRecordCount!),
getAlbumDetail: async (args) => {
const { apiClientProps, context, query } = args;
const { apiClientProps, query } = args;
const albumRes = await ndApiClient(apiClientProps).getAlbumDetail({
params: {
@@ -393,8 +393,6 @@ export const NavidromeController: InternalControllerEndpoint = {
return ndNormalize.album(
{ ...albumRes.body.data, songs: songsData.body.data },
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
);
},
getAlbumInfo: async (args) => {
@@ -418,7 +416,7 @@ export const NavidromeController: InternalControllerEndpoint = {
};
},
getAlbumList: async (args) => {
const { apiClientProps, context, query } = args;
const { apiClientProps, query } = args;
const genres = hasFeature(apiClientProps.server, ServerFeature.BFR)
? query.genreIds
@@ -453,14 +451,7 @@ export const NavidromeController: InternalControllerEndpoint = {
}
return {
items: res.body.data.map((album) =>
ndNormalize.album(
album,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
),
),
items: res.body.data.map((album) => ndNormalize.album(album, apiClientProps.server)),
startIndex: query?.startIndex || 0,
totalRecordCount: Number(res.body.headers.get('x-total-count') || 0),
};
@@ -493,12 +484,7 @@ export const NavidromeController: InternalControllerEndpoint = {
}
return res.body.similarSongs.song.map((song) =>
ssNormalize.song(
song,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
ssNormalize.song(song, apiClientProps.server),
);
},
getArtistList: async (args) => {
@@ -568,12 +554,7 @@ export const NavidromeController: InternalControllerEndpoint = {
}
return res.body.similarSongs2.song.map((song) =>
ssNormalize.song(
song,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
ssNormalize.song(song, apiClientProps.server),
);
},
getDownloadUrl: SubsonicController.getDownloadUrl,
@@ -723,14 +704,7 @@ export const NavidromeController: InternalControllerEndpoint = {
}
return {
items: res.body.data.map((item) =>
ndNormalize.song(
item,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
),
items: res.body.data.map((item) => ndNormalize.song(item, apiClientProps.server)),
startIndex: 0,
totalRecordCount: Number(res.body.headers.get('x-total-count') || 0),
};
@@ -747,14 +721,7 @@ export const NavidromeController: InternalControllerEndpoint = {
const { changedBy, current, items = [], position, updatedAt } = res.body.data; // if there is no queue saved, items is undefined
const entries = items.map((song) =>
ndNormalize.song(
song,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
);
const entries = items.map((song) => ndNormalize.song(song, apiClientProps.server));
return {
changed: updatedAt,
@@ -830,14 +797,7 @@ export const NavidromeController: InternalControllerEndpoint = {
return (
(res.body.similarSongs?.song || [])
.filter((song) => song.id !== query.songId)
.map((song) =>
ssNormalize.song(
song,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
) || []
.map((song) => ssNormalize.song(song, apiClientProps.server)) || []
);
},
getSongDetail: async (args) => {
@@ -853,12 +813,7 @@ export const NavidromeController: InternalControllerEndpoint = {
throw new Error('Failed to get song detail');
}
return ndNormalize.song(
res.body.data,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
);
return ndNormalize.song(res.body.data, apiClientProps.server);
},
getSongList: async (args) => {
const { apiClientProps, query } = args;
@@ -898,14 +853,7 @@ export const NavidromeController: InternalControllerEndpoint = {
}
return {
items: res.body.data.map((song) =>
ndNormalize.song(
song,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
),
items: res.body.data.map((song) => ndNormalize.song(song, apiClientProps.server)),
totalRecordCount: Number(res.body.headers.get('x-total-count') || 0),
};
};
@@ -1022,12 +970,7 @@ export const NavidromeController: InternalControllerEndpoint = {
return {
items: (res.body.topSongs?.song || []).map((song) =>
ssNormalize.song(
song,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
ssNormalize.song(song, apiClientProps.server),
),
startIndex: 0,
totalRecordCount: res.body.topSongs?.song?.length || 0,
@@ -1036,7 +979,6 @@ export const NavidromeController: InternalControllerEndpoint = {
const res = await NavidromeController.getSongList({
apiClientProps,
context: args.context,
query: {
artistIds: [query.artistId],
sortBy: SongListSort.PLAY_COUNT,
@@ -1138,12 +1080,7 @@ export const NavidromeController: InternalControllerEndpoint = {
}
const existingSongs = existingSongsRes.body.data.map((item) =>
ndNormalize.song(
item,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
ndNormalize.song(item, apiClientProps.server),
);
// 2. Get playlist detail to get the name
+37 -186
View File
@@ -482,14 +482,7 @@ export const SubsonicController: InternalControllerEndpoint = {
return {
...ssNormalize.albumArtist(artist, apiClientProps.server),
albums: artist.album?.map((album) =>
ssNormalize.album(
album,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
),
albums: artist.album?.map((album) => ssNormalize.album(album, apiClientProps.server)),
similarArtists: null,
};
},
@@ -564,7 +557,6 @@ export const SubsonicController: InternalControllerEndpoint = {
getAlbumArtistListCount: (args) =>
SubsonicController.getAlbumArtistList({
...args,
context: args.context,
query: { ...args.query, startIndex: 0 },
}).then((res) => res!.totalRecordCount!),
getAlbumDetail: async (args) => {
@@ -580,12 +572,7 @@ export const SubsonicController: InternalControllerEndpoint = {
throw new Error('Failed to get album detail');
}
return ssNormalize.album(
res.body.album,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
);
return ssNormalize.album(res.body.album, apiClientProps.server);
},
getAlbumList: async (args) => {
const { apiClientProps, query } = args;
@@ -610,12 +597,7 @@ export const SubsonicController: InternalControllerEndpoint = {
const results =
res.body.searchResult3?.album?.map((album) =>
ssNormalize.album(
album,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
ssNormalize.album(album, apiClientProps.server),
) || [];
return {
@@ -650,14 +632,7 @@ export const SubsonicController: InternalControllerEndpoint = {
return artist.body.artist.album ?? [];
});
const items = albums.map((album) =>
ssNormalize.album(
album,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
);
const items = albums.map((album) => ssNormalize.album(album, apiClientProps.server));
return {
items: sortAlbumList(items, query.sortBy, query.sortOrder),
@@ -679,12 +654,7 @@ export const SubsonicController: InternalControllerEndpoint = {
const allResults =
res.body.starred?.album?.map((album) =>
ssNormalize.album(
album,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
ssNormalize.album(album, apiClientProps.server),
) || [];
return sortAndPaginate(allResults, {
@@ -749,12 +719,7 @@ export const SubsonicController: InternalControllerEndpoint = {
return {
items:
res.body.albumList2.album?.map((album) =>
ssNormalize.album(
album,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
ssNormalize.album(album, apiClientProps.server),
) || [],
startIndex: query.startIndex,
totalRecordCount: null,
@@ -905,7 +870,7 @@ export const SubsonicController: InternalControllerEndpoint = {
return totalRecordCount;
},
getAlbumRadio: async (args) => {
const { apiClientProps, context, query } = args;
const { apiClientProps, query } = args;
const res = await ssApiClient(apiClientProps).getSimilarSongs({
query: {
@@ -923,12 +888,7 @@ export const SubsonicController: InternalControllerEndpoint = {
}
return res.body.similarSongs.song.map((song) =>
ssNormalize.song(
song,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
),
ssNormalize.song(song, apiClientProps.server),
);
},
getArtistList: async (args) => {
@@ -974,11 +934,10 @@ export const SubsonicController: InternalControllerEndpoint = {
getArtistListCount: async (args) =>
SubsonicController.getArtistList({
...args,
context: args.context,
query: { ...args.query, startIndex: 0 },
}).then((res) => res!.totalRecordCount!),
getArtistRadio: async (args) => {
const { apiClientProps, context, query } = args;
const { apiClientProps, query } = args;
const res = await ssApiClient(apiClientProps).getSimilarSongs2({
query: {
@@ -996,12 +955,7 @@ export const SubsonicController: InternalControllerEndpoint = {
}
return res.body.similarSongs2.song.map((song) =>
ssNormalize.song(
song,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
),
ssNormalize.song(song, apiClientProps.server),
);
},
getDownloadUrl: (args) => {
@@ -1015,7 +969,7 @@ export const SubsonicController: InternalControllerEndpoint = {
'&c=Feishin'
);
},
getFolder: async ({ apiClientProps, context, query }) => {
getFolder: async ({ apiClientProps, query }) => {
const sortOrder = (query.sortOrder?.toLowerCase() ?? 'asc') as 'asc' | 'desc';
const isRootFolderId = query.id === '0';
@@ -1048,14 +1002,7 @@ export const SubsonicController: InternalControllerEndpoint = {
});
}
let folders = items.map((item) =>
ssNormalize.folder(
item,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
),
);
let folders = items.map((item) => ssNormalize.folder(item, apiClientProps.server));
folders = orderBy(folders, [(v) => v.name.toLowerCase()], [sortOrder]);
@@ -1083,12 +1030,7 @@ export const SubsonicController: InternalControllerEndpoint = {
throw new Error('Failed to get folder');
}
const folder = ssNormalize.folder(
directoryRes.body.directory,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
);
const folder = ssNormalize.folder(directoryRes.body.directory, apiClientProps.server);
let filteredFolders = folder.children?.folders || [];
let filteredSongs = folder.children?.songs || [];
@@ -1281,7 +1223,7 @@ export const SubsonicController: InternalControllerEndpoint = {
return results.length;
},
getPlaylistSongList: async ({ apiClientProps, context, query }) => {
getPlaylistSongList: async ({ apiClientProps, query }) => {
const res = await ssApiClient(apiClientProps).getPlaylist({
query: {
id: query.id,
@@ -1294,13 +1236,7 @@ export const SubsonicController: InternalControllerEndpoint = {
const items =
res.body.playlist.entry?.map((song, index) =>
ssNormalize.song(
song,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
index,
),
ssNormalize.song(song, apiClientProps.server, index),
) || [];
return {
@@ -1309,7 +1245,7 @@ export const SubsonicController: InternalControllerEndpoint = {
totalRecordCount: items.length,
};
},
getPlayQueue: async ({ apiClientProps, context }) => {
getPlayQueue: async ({ apiClientProps }) => {
if (hasFeature(apiClientProps.server, ServerFeature.SERVER_PLAY_QUEUE)) {
const res = await ssApiClient(apiClientProps).getPlayQueueByIndex();
@@ -1324,15 +1260,7 @@ export const SubsonicController: InternalControllerEndpoint = {
changed: changed ?? '',
changedBy: changedBy ?? '',
currentIndex: currentIndex ?? 0,
entry:
entry?.map((song) =>
ssNormalize.song(
song,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
),
) || [],
entry: entry?.map((song) => ssNormalize.song(song, apiClientProps.server)) || [],
positionMs: position ?? 0,
username: username ?? '',
};
@@ -1349,22 +1277,14 @@ export const SubsonicController: InternalControllerEndpoint = {
changed,
changedBy,
currentIndex: current ? entry.findIndex((item) => item.id === current) : 0,
entry:
entry?.map((song) =>
ssNormalize.song(
song,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
),
) || [],
entry: entry?.map((song) => ssNormalize.song(song, apiClientProps.server)) || [],
positionMs: position ?? 0,
username,
};
}
},
getRandomSongList: async (args) => {
const { apiClientProps, context, query } = args;
const { apiClientProps, query } = args;
const res = await ssApiClient(apiClientProps).getRandomSongList({
query: {
@@ -1382,12 +1302,7 @@ export const SubsonicController: InternalControllerEndpoint = {
const results = res.body.randomSongs?.song || [];
const normalizedResults = results.map((song) =>
ssNormalize.song(
song,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
),
ssNormalize.song(song, apiClientProps.server),
);
return {
@@ -1473,7 +1388,7 @@ export const SubsonicController: InternalControllerEndpoint = {
return { features, id: apiClientProps.server?.id, version: ping.body.serverVersion };
},
getSimilarSongs: async (args) => {
const { apiClientProps, context, query } = args;
const { apiClientProps, query } = args;
const res = await ssApiClient(apiClientProps).getSimilarSongs({
query: {
@@ -1492,21 +1407,14 @@ export const SubsonicController: InternalControllerEndpoint = {
return res.body.similarSongs.song.reduce<Song[]>((acc, song) => {
if (song.id !== query.songId) {
acc.push(
ssNormalize.song(
song,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
),
);
acc.push(ssNormalize.song(song, apiClientProps.server));
}
return acc;
}, []);
},
getSongDetail: async (args) => {
const { apiClientProps, context, query } = args;
const { apiClientProps, query } = args;
const res = await ssApiClient(apiClientProps).getSong({
query: {
@@ -1518,14 +1426,9 @@ export const SubsonicController: InternalControllerEndpoint = {
throw new Error('Failed to get song detail');
}
return ssNormalize.song(
res.body.song,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
);
return ssNormalize.song(res.body.song, apiClientProps.server);
},
getSongList: async ({ apiClientProps, context, query }) => {
getSongList: async ({ apiClientProps, query }) => {
const fromAlbumPromises: Promise<ServerInferResponses<typeof contract.getAlbum>>[] = [];
const artistDetailPromises: Promise<ServerInferResponses<typeof contract.getArtist>>[] = [];
@@ -1550,12 +1453,7 @@ export const SubsonicController: InternalControllerEndpoint = {
return {
items:
res.body.searchResult3?.song?.map((song) =>
ssNormalize.song(
song,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
),
ssNormalize.song(song, apiClientProps.server),
) || [],
startIndex: query.startIndex,
totalRecordCount: null,
@@ -1579,15 +1477,7 @@ export const SubsonicController: InternalControllerEndpoint = {
const results = res.body.songsByGenre?.song || [];
return {
items:
results.map((song) =>
ssNormalize.song(
song,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
),
) || [],
items: results.map((song) => ssNormalize.song(song, apiClientProps.server)) || [],
startIndex: 0,
totalRecordCount: null,
};
@@ -1606,12 +1496,7 @@ export const SubsonicController: InternalControllerEndpoint = {
let allResults =
(res.body.starred?.song || []).map((song) =>
ssNormalize.song(
song,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
),
ssNormalize.song(song, apiClientProps.server),
) || [];
const filterArtistIds = query.albumArtistIds || query.artistIds;
@@ -1696,15 +1581,7 @@ export const SubsonicController: InternalControllerEndpoint = {
}
return {
items:
results.map((song) =>
ssNormalize.song(
song,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
),
) || [],
items: results.map((song) => ssNormalize.song(song, apiClientProps.server)) || [],
startIndex: 0,
totalRecordCount: results.length,
};
@@ -1730,12 +1607,7 @@ export const SubsonicController: InternalControllerEndpoint = {
return {
items:
res.body.searchResult3?.song?.map((song) =>
ssNormalize.song(
song,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
),
ssNormalize.song(song, apiClientProps.server),
) || [],
startIndex: 0,
totalRecordCount: null,
@@ -2103,7 +1975,7 @@ export const SubsonicController: InternalControllerEndpoint = {
});
},
getTopSongs: async (args) => {
const { apiClientProps, context, query } = args;
const { apiClientProps, query } = args;
const type = query.type === 'personal' ? 'personal' : 'community';
@@ -2121,12 +1993,7 @@ export const SubsonicController: InternalControllerEndpoint = {
return {
items: (res.body.topSongs?.song || []).map((song) =>
ssNormalize.song(
song,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
),
ssNormalize.song(song, apiClientProps.server),
),
startIndex: 0,
totalRecordCount: res.body.topSongs?.song?.length || 0,
@@ -2135,7 +2002,6 @@ export const SubsonicController: InternalControllerEndpoint = {
const res = await SubsonicController.getSongList({
apiClientProps,
context,
query: {
artistIds: [query.artistId],
sortBy: SongListSort.PLAY_COUNT,
@@ -2190,7 +2056,7 @@ export const SubsonicController: InternalControllerEndpoint = {
return null;
},
replacePlaylist: async (args) => {
const { apiClientProps, body, context, query } = args;
const { apiClientProps, body, query } = args;
// 1. Fetch existing songs from the playlist
const existingSongsRes = await ssApiClient(apiClientProps).getPlaylist({
@@ -2205,12 +2071,7 @@ export const SubsonicController: InternalControllerEndpoint = {
const existingSongs =
existingSongsRes.body.playlist.entry?.map((song) =>
ssNormalize.song(
song,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
),
ssNormalize.song(song, apiClientProps.server),
) || [];
// 2. Get playlist detail to get the name
@@ -2388,7 +2249,7 @@ export const SubsonicController: InternalControllerEndpoint = {
return null;
},
search: async (args) => {
const { apiClientProps, context, query } = args;
const { apiClientProps, query } = args;
const res = await ssApiClient(apiClientProps).search3({
query: {
@@ -2412,20 +2273,10 @@ export const SubsonicController: InternalControllerEndpoint = {
ssNormalize.albumArtist(artist, apiClientProps.server),
),
albums: (res.body.searchResult3?.album || []).map((album) =>
ssNormalize.album(
album,
apiClientProps.server,
args.context?.pathReplace,
args.context?.pathReplaceWith,
),
ssNormalize.album(album, apiClientProps.server),
),
songs: (res.body.searchResult3?.song || []).map((song) =>
ssNormalize.song(
song,
apiClientProps.server,
context?.pathReplace,
context?.pathReplaceWith,
),
ssNormalize.song(song, apiClientProps.server),
),
};
},