mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-09 20:29:36 +02:00
Add all relevant subsonic endpoints to ts-rest
This commit is contained in:
@@ -1,93 +1,426 @@
|
|||||||
import { initClient, initContract } from '@ts-rest/core';
|
import { initClient, initContract } from '@ts-rest/core';
|
||||||
import axios, { Method, AxiosError, isAxiosError, AxiosResponse } from 'axios';
|
import axios, { AxiosError, AxiosResponse, Method, isAxiosError } from 'axios';
|
||||||
import omitBy from 'lodash/omitBy';
|
import omitBy from 'lodash/omitBy';
|
||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
import { z } from 'zod';
|
import i18n from '/@/i18n/i18n';
|
||||||
import { ssType } from '/@/renderer/api/subsonic/subsonic-types';
|
import { SubsonicApi } from '/@/renderer/api/subsonic/subsonic-types';
|
||||||
import { ServerListItem } from '/@/renderer/api/types';
|
import { ServerListItem } from '/@/renderer/api/types';
|
||||||
import { toast } from '/@/renderer/components/toast/index';
|
import { toast } from '/@/renderer/components/toast/index';
|
||||||
import i18n from '/@/i18n/i18n';
|
|
||||||
|
|
||||||
const c = initContract();
|
const c = initContract();
|
||||||
|
|
||||||
export const contract = c.router({
|
export const contract = c.router({
|
||||||
authenticate: {
|
changePassword: {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: 'ping.view',
|
path: 'changePassword.view',
|
||||||
query: ssType._parameters.authenticate,
|
query: SubsonicApi.changePassword.parameters,
|
||||||
responses: {
|
responses: {
|
||||||
200: ssType._response.authenticate,
|
200: SubsonicApi.changePassword.response,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
createFavorite: {
|
createInternetRadioStation: {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: 'star.view',
|
path: 'createInternetRadioStation.view',
|
||||||
query: ssType._parameters.createFavorite,
|
query: SubsonicApi.createInternetRadioStation.parameters,
|
||||||
responses: {
|
responses: {
|
||||||
200: ssType._response.createFavorite,
|
200: SubsonicApi.createInternetRadioStation.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
createPlaylist: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'createPlaylist.view',
|
||||||
|
query: SubsonicApi.createPlaylist.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.createPlaylist.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
createShare: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'createShare.view',
|
||||||
|
query: SubsonicApi.createShare.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.createShare.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
createUser: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'createUser.view',
|
||||||
|
query: SubsonicApi.createUser.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.createUser.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
deleteInternetRadioStation: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'deleteInternetRadioStation.view',
|
||||||
|
query: SubsonicApi.deleteInternetRadioStation.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.deleteInternetRadioStation.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
deletePlaylist: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'deletePlaylist.view',
|
||||||
|
query: SubsonicApi.deletePlaylist.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.deletePlaylist.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
deleteShare: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'deleteShare.view',
|
||||||
|
query: SubsonicApi.deleteShare.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.deleteShare.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
deleteUser: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'deleteUser.view',
|
||||||
|
query: SubsonicApi.deleteUser.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.deleteUser.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getAlbum: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getAlbum.view',
|
||||||
|
query: SubsonicApi.getAlbum.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getAlbum.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getAlbumInfo: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getAlbumInfo.view',
|
||||||
|
query: SubsonicApi.getAlbumInfo.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getAlbumInfo.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getAlbumInfo2: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getAlbumInfo2.view',
|
||||||
|
query: SubsonicApi.getAlbumInfo2.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getAlbumInfo2.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getAlbumList: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getAlbumList.view',
|
||||||
|
query: SubsonicApi.getAlbumList.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getAlbumList.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getAlbumList2: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getAlbumList2.view',
|
||||||
|
query: SubsonicApi.getAlbumList2.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getAlbumList2.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getArtist: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getArtist.view',
|
||||||
|
query: SubsonicApi.getArtist.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getArtist.response,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
getArtistInfo: {
|
getArtistInfo: {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: 'getArtistInfo.view',
|
path: 'getArtistInfo.view',
|
||||||
query: ssType._parameters.artistInfo,
|
query: SubsonicApi.getArtistInfo.parameters,
|
||||||
responses: {
|
responses: {
|
||||||
200: ssType._response.artistInfo,
|
200: SubsonicApi.getArtistInfo.response,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
getMusicFolderList: {
|
getArtistInfo2: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getArtistInfo2.view',
|
||||||
|
query: SubsonicApi.getArtistInfo2.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getArtistInfo2.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getArtists: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getArtists.view',
|
||||||
|
query: SubsonicApi.getArtists.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getArtists.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getGenres: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getGenres.view',
|
||||||
|
query: SubsonicApi.getGenres.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getGenres.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getIndexes: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getIndexes.view',
|
||||||
|
query: SubsonicApi.getIndexes.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getIndexes.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getInternetRadioStations: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getInternetRadioStations.view',
|
||||||
|
query: SubsonicApi.getInternetRadioStations.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getInternetRadioStations.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getLicense: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getLicense.view',
|
||||||
|
query: SubsonicApi.getLicense.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getLicense.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getLyrics: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getLyrics.view',
|
||||||
|
query: SubsonicApi.getLyrics.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getLyrics.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getMusicDirectory: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getMusicDirectory.view',
|
||||||
|
query: SubsonicApi.getMusicDirectory.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getMusicDirectory.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getMusicFolders: {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: 'getMusicFolders.view',
|
path: 'getMusicFolders.view',
|
||||||
responses: {
|
responses: {
|
||||||
200: ssType._response.musicFolderList,
|
200: SubsonicApi.getMusicFolders.response,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
getRandomSongList: {
|
getNowPlaying: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getNowPlaying.view',
|
||||||
|
query: SubsonicApi.getNowPlaying.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getNowPlaying.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getOpenSubsonicExtensions: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getOpenSubsonicExtensions.view',
|
||||||
|
query: SubsonicApi.getOpenSubsonicExtensions.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getOpenSubsonicExtensions.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getPlaylist: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getPlaylist.view',
|
||||||
|
query: SubsonicApi.getPlaylist.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getPlaylist.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getPlaylists: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getPlaylists.view',
|
||||||
|
query: SubsonicApi.getPlaylists.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getPlaylists.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getRandomSongs: {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: 'getRandomSongs.view',
|
path: 'getRandomSongs.view',
|
||||||
query: ssType._parameters.randomSongList,
|
query: SubsonicApi.getRandomSongs.parameters,
|
||||||
responses: {
|
responses: {
|
||||||
200: ssType._response.randomSongList,
|
200: SubsonicApi.getRandomSongs.response,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
getTopSongsList: {
|
getScanStatus: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getScanStatus.view',
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getScanStatus.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getShares: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getShares.view',
|
||||||
|
query: SubsonicApi.getShares.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getShares.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getSimilarSongs: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getSimilarSongs.view',
|
||||||
|
query: SubsonicApi.getSimilarSongs.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getSimilarSongs.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getSimilarSongs2: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getSimilarSongs2.view',
|
||||||
|
query: SubsonicApi.getSimilarSongs2.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getSimilarSongs2.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getSong: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getSong.view',
|
||||||
|
query: SubsonicApi.getSong.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getSong.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getSongsByGenre: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getSongsByGenre.view',
|
||||||
|
query: SubsonicApi.getSongsByGenre.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getSongsByGenre.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getStarred: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getStarred.view',
|
||||||
|
query: SubsonicApi.getStarred.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getStarred.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getStarred2: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getStarred2.view',
|
||||||
|
query: SubsonicApi.getStarred2.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getStarred2.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getTopSongs: {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: 'getTopSongs.view',
|
path: 'getTopSongs.view',
|
||||||
query: ssType._parameters.topSongsList,
|
query: SubsonicApi.getTopSongs.parameters,
|
||||||
responses: {
|
responses: {
|
||||||
200: ssType._response.topSongsList,
|
200: SubsonicApi.getTopSongs.response,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
removeFavorite: {
|
getUser: {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: 'unstar.view',
|
path: 'getUser.view',
|
||||||
query: ssType._parameters.removeFavorite,
|
query: SubsonicApi.getUser.parameters,
|
||||||
responses: {
|
responses: {
|
||||||
200: ssType._response.removeFavorite,
|
200: SubsonicApi.getUser.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getUsers: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'getUsers.view',
|
||||||
|
query: SubsonicApi.getUsers.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.getUsers.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ping: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'ping.view',
|
||||||
|
query: SubsonicApi.ping.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.ping.response,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
scrobble: {
|
scrobble: {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: 'scrobble.view',
|
path: 'scrobble.view',
|
||||||
query: ssType._parameters.scrobble,
|
query: SubsonicApi.scrobble.parameters,
|
||||||
responses: {
|
responses: {
|
||||||
200: ssType._response.scrobble,
|
200: SubsonicApi.scrobble.response,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
search3: {
|
search3: {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: 'search3.view',
|
path: 'search3.view',
|
||||||
query: ssType._parameters.search3,
|
query: SubsonicApi.search3.parameters,
|
||||||
responses: {
|
responses: {
|
||||||
200: ssType._response.search3,
|
200: SubsonicApi.search3.response,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
setRating: {
|
setRating: {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: 'setRating.view',
|
path: 'setRating.view',
|
||||||
query: ssType._parameters.setRating,
|
query: SubsonicApi.setRating.parameters,
|
||||||
responses: {
|
responses: {
|
||||||
200: ssType._response.setRating,
|
200: SubsonicApi.setRating.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
star: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'star.view',
|
||||||
|
query: SubsonicApi.star.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.star.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
startScan: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'startScan.view',
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.startScan.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
unstar: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'unstar.view',
|
||||||
|
query: SubsonicApi.unstar.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.unstar.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
updateInternetRadioStation: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'updateInternetRadioStation.view',
|
||||||
|
query: SubsonicApi.updateInternetRadioStation.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.updateInternetRadioStation.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
updatePlaylist: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'updatePlaylist.view',
|
||||||
|
query: SubsonicApi.updatePlaylist.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.updatePlaylist.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
updateShare: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'updateShare.view',
|
||||||
|
query: SubsonicApi.updateShare.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.updateShare.response,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
updateUser: {
|
||||||
|
method: 'GET',
|
||||||
|
path: 'updateUser.view',
|
||||||
|
query: SubsonicApi.updateUser.parameters,
|
||||||
|
responses: {
|
||||||
|
200: SubsonicApi.updateUser.response,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -110,6 +443,8 @@ axiosClient.interceptors.response.use(
|
|||||||
title: i18n.t('error.genericError', { postProcess: 'sentenceCase' }) as string,
|
title: i18n.t('error.genericError', { postProcess: 'sentenceCase' }) as string,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Promise.reject(data['subsonic-response'].error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
@@ -131,7 +466,7 @@ const parsePath = (fullPath: string) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ssApiClient = (args: {
|
export const subsonicApiClient = (args: {
|
||||||
server: ServerListItem | null;
|
server: ServerListItem | null;
|
||||||
signal?: AbortSignal;
|
signal?: AbortSignal;
|
||||||
url?: string;
|
url?: string;
|
||||||
@@ -162,9 +497,7 @@ export const ssApiClient = (args: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await axiosClient.request<
|
const result = await axiosClient.request({
|
||||||
z.infer<typeof ssType._response.baseResponse>
|
|
||||||
>({
|
|
||||||
data: body,
|
data: body,
|
||||||
headers,
|
headers,
|
||||||
method: method as Method,
|
method: method as Method,
|
||||||
@@ -180,7 +513,7 @@ export const ssApiClient = (args: {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
body: result.data['subsonic-response'],
|
body: result.data,
|
||||||
headers: result.headers as any,
|
headers: result.headers as any,
|
||||||
status: result.status,
|
status: result.status,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { nanoid } from 'nanoid';
|
import { nanoid } from 'nanoid';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { ssType } from '/@/renderer/api/subsonic/subsonic-types';
|
import { SubsonicApi } from '/@/renderer/api/subsonic/subsonic-types';
|
||||||
import { QueueSong, LibraryItem, AlbumArtist, Album } from '/@/renderer/api/types';
|
import { QueueSong, LibraryItem, AlbumArtist, Album, Genre } from '/@/renderer/api/types';
|
||||||
import { ServerListItem, ServerType } from '/@/renderer/types';
|
import { ServerListItem, ServerType } from '/@/renderer/types';
|
||||||
|
|
||||||
const getCoverArtUrl = (args: {
|
const getCoverArtUrl = (args: {
|
||||||
@@ -27,7 +27,7 @@ const getCoverArtUrl = (args: {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const normalizeSong = (
|
const normalizeSong = (
|
||||||
item: z.infer<typeof ssType._response.song>,
|
item: z.infer<typeof SubsonicApi._baseTypes.song>,
|
||||||
server: ServerListItem | null,
|
server: ServerListItem | null,
|
||||||
deviceId: string,
|
deviceId: string,
|
||||||
): QueueSong => {
|
): QueueSong => {
|
||||||
@@ -105,7 +105,7 @@ const normalizeSong = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const normalizeAlbumArtist = (
|
const normalizeAlbumArtist = (
|
||||||
item: z.infer<typeof ssType._response.albumArtist>,
|
item: z.infer<typeof SubsonicApi._baseTypes.artist>,
|
||||||
server: ServerListItem | null,
|
server: ServerListItem | null,
|
||||||
): AlbumArtist => {
|
): AlbumArtist => {
|
||||||
const imageUrl =
|
const imageUrl =
|
||||||
@@ -138,7 +138,9 @@ const normalizeAlbumArtist = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const normalizeAlbum = (
|
const normalizeAlbum = (
|
||||||
item: z.infer<typeof ssType._response.album>,
|
item:
|
||||||
|
| z.infer<typeof SubsonicApi._baseTypes.album>
|
||||||
|
| z.infer<typeof SubsonicApi._baseTypes.albumListEntry>,
|
||||||
server: ServerListItem | null,
|
server: ServerListItem | null,
|
||||||
): Album => {
|
): Album => {
|
||||||
const imageUrl =
|
const imageUrl =
|
||||||
@@ -189,8 +191,20 @@ const normalizeAlbum = (
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ssNormalize = {
|
const normalizeGenre = (item: z.infer<typeof SubsonicApi._baseTypes.genre>): Genre => {
|
||||||
|
return {
|
||||||
|
albumCount: item.albumCount,
|
||||||
|
id: item.value,
|
||||||
|
imageUrl: null,
|
||||||
|
itemType: LibraryItem.GENRE,
|
||||||
|
name: item.value,
|
||||||
|
songCount: item.songCount,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const subsonicNormalize = {
|
||||||
album: normalizeAlbum,
|
album: normalizeAlbum,
|
||||||
albumArtist: normalizeAlbumArtist,
|
albumArtist: normalizeAlbumArtist,
|
||||||
|
genre: normalizeGenre,
|
||||||
song: normalizeSong,
|
song: normalizeSong,
|
||||||
};
|
};
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user