Files
feishin/src/renderer/api/controller.ts
T
Derek Simonds fd9380a149 feat: adds option to view top rated songs in the Favorite Songs section (#2289)
* Adds Top Rating option songs to Artist's favorite songs section
2026-08-03 19:36:08 -07:00

1134 lines
35 KiB
TypeScript

import i18n from '/@/i18n/i18n';
import { JellyfinController } from '/@/renderer/api/jellyfin/jellyfin-controller';
import { NavidromeController } from '/@/renderer/api/navidrome/navidrome-controller';
import { SubsonicController } from '/@/renderer/api/subsonic/subsonic-controller';
import { mergeMusicFolderId } from '/@/renderer/api/utils-music-folder';
import { getServerById, useAuthStore, useSettingsStore } from '/@/renderer/store';
import { logger } from '/@/renderer/utils/logger';
import { toast } from '/@/shared/components/toast/toast';
import {
AuthenticationResponse,
ControllerEndpoint,
InternalControllerEndpoint,
ServerType,
SetPlaylistSongsArgs,
SetPlaylistSongsResponse,
} from '/@/shared/types/domain-types';
type ApiController = {
jellyfin: InternalControllerEndpoint;
navidrome: InternalControllerEndpoint;
subsonic: InternalControllerEndpoint;
};
const endpoints: ApiController = {
jellyfin: JellyfinController,
navidrome: NavidromeController,
subsonic: SubsonicController,
};
const SENSITIVE_KEY_PATTERN = /password|token|credential|authorization|secret|cookie/i;
const MAX_ARRAY_ITEMS = 20;
const MAX_STRING_LENGTH = 200;
const sanitizeValue = (value: unknown, depth = 0): unknown => {
if (value === null || value === undefined) {
return value;
}
if (typeof value === 'string') {
return value.length > MAX_STRING_LENGTH
? `${value.slice(0, MAX_STRING_LENGTH)}…(${value.length})`
: value;
}
if (typeof value !== 'object') {
return value;
}
if (depth >= 4) {
return '[Truncated]';
}
if (Array.isArray(value)) {
const items = value.slice(0, MAX_ARRAY_ITEMS).map((item) => sanitizeValue(item, depth + 1));
if (value.length > MAX_ARRAY_ITEMS) {
items.push(`…(+${value.length - MAX_ARRAY_ITEMS} more)`);
}
return items;
}
const result: Record<string, unknown> = {};
for (const [key, nested] of Object.entries(value as Record<string, unknown>)) {
if (SENSITIVE_KEY_PATTERN.test(key)) {
result[key] = '[Redacted]';
continue;
}
result[key] = sanitizeValue(nested, depth + 1);
}
return result;
};
const OMITTED_CONTROLLER_ARG_KEYS = new Set([
'apiClientProps',
'body',
'context',
'query',
'signal',
]);
const sanitizeControllerArgs = (endpoint: string, args: unknown[]): unknown => {
if (endpoint === 'authenticate') {
const [url] = args;
return { url: typeof url === 'string' ? url : undefined };
}
const first = args[0];
if (!first || typeof first !== 'object') {
return args.length === 0 ? undefined : sanitizeValue(args);
}
const input = first as Record<string, unknown>;
const sanitized: Record<string, unknown> = {};
if (input.query !== undefined) {
sanitized.query = sanitizeValue(input.query);
}
if (input.body !== undefined) {
sanitized.body = sanitizeValue(input.body);
}
for (const [key, value] of Object.entries(input)) {
if (OMITTED_CONTROLLER_ARG_KEYS.has(key)) {
continue;
}
sanitized[key] = sanitizeValue(value);
}
return sanitized;
};
const OMITTED_CONTROLLER_LOG_ENDPOINTS = new Set<keyof ControllerEndpoint>([
'getDownloadUrl',
'getImageRequest',
'getImageUrl',
'getStreamUrl',
]);
const apiController = <K extends keyof ControllerEndpoint>(
endpoint: K,
type?: ServerType,
): NonNullable<InternalControllerEndpoint[K]> => {
const serverType = type || useAuthStore.getState().currentServer?.type;
if (!serverType) {
toast.error({
message: i18n.t('error.serverNotSelectedError') as string,
title: i18n.t('error.apiRouteError') as string,
});
logger.error('No server selected', {
serverType,
});
throw new Error(`No server selected`);
}
const controllerFn = endpoints?.[serverType]?.[endpoint];
if (typeof controllerFn !== 'function') {
logger.error(`Endpoint ${endpoint} is not implemented for ${serverType}`, {
endpoint,
serverType,
});
throw new Error(
i18n.t('error.endpointNotImplementedError', {
endpoint,
serverType,
}) as string,
);
}
if (OMITTED_CONTROLLER_LOG_ENDPOINTS.has(endpoint)) {
return controllerFn;
}
return ((...args: unknown[]) => {
const started = performance.now();
const serverId = (args[0] as undefined | { apiClientProps?: { serverId?: string } })
?.apiClientProps?.serverId;
const logResult = (error?: unknown, value?: unknown) => {
logger.debug(`Controller ${String(endpoint)}${error != null ? ' failed' : ''}`, {
args: sanitizeControllerArgs(String(endpoint), args),
durationMs: Math.round(performance.now() - started),
serverId,
serverType,
...(error != null
? { error: error instanceof Error ? error.message : String(error) }
: { result: sanitizeValue(value) }),
});
};
try {
const result = (controllerFn as (...a: unknown[]) => unknown)(...args);
if (result instanceof Promise) {
return result.then(
(value) => {
logResult(undefined, value);
return value;
},
(error) => {
logResult(error);
throw error;
},
);
}
logResult(undefined, result);
return result;
} catch (error) {
logResult(error);
throw error;
}
}) as NonNullable<InternalControllerEndpoint[K]>;
};
const getPathReplaceSettings = () => {
const { pathReplace, pathReplaceWith } = useSettingsStore.getState().general;
return { pathReplace, pathReplaceWith };
};
const addContext = <T extends { apiClientProps: any; context?: any }>(args: T): T => {
const pathSettings = getPathReplaceSettings();
return {
...args,
context: {
...(args.context || {}),
...pathSettings,
},
};
};
export interface GeneralController extends Omit<Required<ControllerEndpoint>, 'authenticate'> {
authenticate: (
url: string,
body: { legacy?: boolean; password: string; username: string },
type: ServerType,
) => Promise<AuthenticationResponse>;
}
export const controller: GeneralController = {
addToPlaylist(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: addToPlaylist`);
}
return apiController(
'addToPlaylist',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
authenticate(url, body, type) {
return apiController('authenticate', type)(url, body);
},
createFavorite(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: createFavorite`);
}
return apiController(
'createFavorite',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
createInternetRadioStation(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: createInternetRadioStation`);
}
return apiController(
'createInternetRadioStation',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
createPlaylist(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: createPlaylist`);
}
return apiController(
'createPlaylist',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
deleteArtistImage(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: deleteArtistImage`);
}
return apiController(
'deleteArtistImage',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
deleteFavorite(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: deleteFavorite`);
}
return apiController(
'deleteFavorite',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
deleteInternetRadioStation(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: deleteInternetRadioStation`);
}
return apiController(
'deleteInternetRadioStation',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
deleteInternetRadioStationImage(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: deleteInternetRadioStationImage`);
}
return apiController(
'deleteInternetRadioStationImage',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
deletePlaylist(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: deletePlaylist`);
}
return apiController(
'deletePlaylist',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
deletePlaylistImage(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: deletePlaylistImage`);
}
return apiController(
'deletePlaylistImage',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getAlbumArtistDetail(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getAlbumArtistDetail`);
}
return apiController(
'getAlbumArtistDetail',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getAlbumArtistInfo(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
return Promise.resolve(null);
}
const fn = apiController('getAlbumArtistInfo', server.type);
return fn
? fn(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }))
: Promise.resolve(null);
},
getAlbumArtistList(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getAlbumArtistList`);
}
return apiController(
'getAlbumArtistList',
server.type,
)?.(
addContext({
...args,
apiClientProps: { ...args.apiClientProps, server },
query: mergeMusicFolderId(args.query, server),
}),
);
},
getAlbumArtistListCount(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getAlbumArtistListCount`);
}
return apiController(
'getAlbumArtistListCount',
server.type,
)?.(
addContext({
...args,
apiClientProps: { ...args.apiClientProps, server },
query: mergeMusicFolderId(args.query, server),
}),
);
},
getAlbumDetail(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getAlbumDetail`);
}
return apiController(
'getAlbumDetail',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getAlbumInfo(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getAlbumInfo`);
}
return apiController(
'getAlbumInfo',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getAlbumList(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getAlbumList`);
}
return apiController(
'getAlbumList',
server.type,
)?.(
addContext({
...args,
apiClientProps: { ...args.apiClientProps, server },
query: mergeMusicFolderId(args.query, server),
}),
);
},
getAlbumListCount(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getAlbumListCount`);
}
return apiController(
'getAlbumListCount',
server.type,
)?.(
addContext({
...args,
apiClientProps: { ...args.apiClientProps, server },
query: mergeMusicFolderId(args.query, server),
}),
);
},
getAlbumRadio(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getAlbumRadio`);
}
return apiController(
'getAlbumRadio',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getArtistList(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getArtistList`);
}
return apiController(
'getArtistList',
server.type,
)?.(
addContext({
...args,
apiClientProps: { ...args.apiClientProps, server },
query: mergeMusicFolderId(args.query, server),
}),
);
},
getArtistListCount(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getArtistListCount`);
}
return apiController(
'getArtistListCount',
server.type,
)?.(
addContext({
...args,
apiClientProps: { ...args.apiClientProps, server },
query: mergeMusicFolderId(args.query, server),
}),
);
},
getArtistRadio(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getArtistRadio`);
}
return apiController(
'getArtistRadio',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getDownloadUrl(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getDownloadUrl`);
}
return apiController(
'getDownloadUrl',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getFavoriteSongs(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getFavoriteSongs`);
}
return apiController(
'getFavoriteSongs',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getFolder(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getFolder`);
}
return apiController(
'getFolder',
server.type,
)?.(
addContext({
...args,
apiClientProps: { ...args.apiClientProps, server },
query: mergeMusicFolderId(args.query, server),
}),
);
},
getGenreList(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getGenreList`);
}
return apiController(
'getGenreList',
server.type,
)?.(
addContext({
...args,
apiClientProps: { ...args.apiClientProps, server },
query: mergeMusicFolderId(args.query, server),
}),
);
},
getImageRequest(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
return null;
}
return (
apiController(
'getImageRequest',
server.type,
)?.(
addContext({
...args,
apiClientProps: { ...args.apiClientProps, server },
}),
) || null
);
},
getImageUrl(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
return null;
}
return (
apiController(
'getImageUrl',
server.type,
)?.(
addContext({
...args,
apiClientProps: { ...args.apiClientProps, server },
}),
) || null
);
},
getInternetRadioStations(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getInternetRadioStations`);
}
return apiController(
'getInternetRadioStations',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getLyrics(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getLyrics`);
}
return apiController(
'getLyrics',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getMusicFolderList(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getMusicFolderList`);
}
return apiController(
'getMusicFolderList',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getPlaylistDetail(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getPlaylistDetail`);
}
return apiController(
'getPlaylistDetail',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getPlaylistList(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getPlaylistList`);
}
return apiController(
'getPlaylistList',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getPlaylistListCount(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getPlaylistListCount`);
}
return apiController(
'getPlaylistListCount',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getPlaylistSongIds(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getPlaylistSongIds`);
}
return apiController(
'getPlaylistSongIds',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getPlaylistSongList(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getPlaylistSongList`);
}
return apiController(
'getPlaylistSongList',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getPlayQueue(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getPlayQueue`);
}
return apiController(
'getPlayQueue',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getRandomSongList(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getRandomSongList`);
}
return apiController(
'getRandomSongList',
server.type,
)?.(
addContext({
...args,
apiClientProps: { ...args.apiClientProps, server },
query: mergeMusicFolderId(args.query, server),
}),
);
},
getRoles(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getRoles`);
}
return apiController(
'getRoles',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getScanStatus(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getScanStatus`);
}
return apiController(
'getScanStatus',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getServerInfo(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getServerInfo`);
}
return apiController(
'getServerInfo',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getSimilarSongs(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getSimilarSongs`);
}
return apiController(
'getSimilarSongs',
server.type,
)?.(
addContext({
...args,
apiClientProps: { ...args.apiClientProps, server },
query: mergeMusicFolderId(args.query, server),
}),
);
},
getSongDetail(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getSongDetail`);
}
return apiController(
'getSongDetail',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getSongList(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getSongList`);
}
return apiController(
'getSongList',
server.type,
)?.(
addContext({
...args,
apiClientProps: { ...args.apiClientProps, server },
query: mergeMusicFolderId(args.query, server),
}),
);
},
getSongListCount(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getSongListCount`);
}
return apiController(
'getSongListCount',
server.type,
)?.(
addContext({
...args,
apiClientProps: { ...args.apiClientProps, server },
query: mergeMusicFolderId(args.query, server),
}),
);
},
getStreamUrl(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getStreamUrl`);
}
return apiController(
'getStreamUrl',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getStructuredLyrics(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getStructuredLyrics`);
}
return apiController(
'getStructuredLyrics',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getTagList(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getTags`);
}
return apiController(
'getTagList',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getTopSongs(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getTopSongs`);
}
return apiController(
'getTopSongs',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getUserInfo(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getUserInfo`);
}
return apiController(
'getUserInfo',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
getUserList(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: getUserList`);
}
return apiController(
'getUserList',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
jukeboxControl(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: jukeboxControl`);
}
const fn = apiController('jukeboxControl', server.type);
return fn
? fn(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }))
: Promise.resolve(null);
},
movePlaylistItem(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: movePlaylistItem`);
}
return apiController(
'movePlaylistItem',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
refreshItems(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: refreshItems`);
}
return apiController(
'refreshItems',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
removeFromPlaylist(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: removeFromPlaylist`);
}
return apiController(
'removeFromPlaylist',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
replacePlaylist(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: replacePlaylist`);
}
return apiController(
'replacePlaylist',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
savePlayQueue(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: savePlayQueue`);
}
return apiController(
'savePlayQueue',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
scrobble(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: scrobble`);
}
return apiController(
'scrobble',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
search(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: search`);
}
return apiController(
'search',
server.type,
)?.(
addContext({
...args,
apiClientProps: { ...args.apiClientProps, server },
query: mergeMusicFolderId(args.query, server),
}),
);
},
setPlaylistSongs: function (args: SetPlaylistSongsArgs): Promise<SetPlaylistSongsResponse> {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: setPlaylistSongs`);
}
return apiController(
'setPlaylistSongs',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
setRating(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: setRating`);
}
return apiController(
'setRating',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
shareItem(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: shareItem`);
}
return apiController(
'shareItem',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
startLibraryScan(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: startLibraryScan`);
}
return apiController(
'startLibraryScan',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
updateInternetRadioStation(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: updateInternetRadioStation`);
}
return apiController(
'updateInternetRadioStation',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
updatePlaylist(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: updatePlaylist`);
}
return apiController(
'updatePlaylist',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
uploadArtistImage(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: uploadArtistImage`);
}
return apiController(
'uploadArtistImage',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
uploadInternetRadioStationImage(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: uploadInternetRadioStationImage`);
}
return apiController(
'uploadInternetRadioStationImage',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
uploadPlaylistImage(args) {
const server = getServerById(args.apiClientProps.serverId);
if (!server) {
throw new Error(`${i18n.t('error.apiRouteError')}: uploadPlaylistImage`);
}
return apiController(
'uploadPlaylistImage',
server.type,
)?.(addContext({ ...args, apiClientProps: { ...args.apiClientProps, server } }));
},
};