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
@@ -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