Additional refactor for navidrome api controller types

This commit is contained in:
jeffvli 2023-04-30 17:55:23 -07:00
parent b9d5447b4f
commit 40aabd2217
7 changed files with 53 additions and 48 deletions

View File

@ -4,7 +4,7 @@ import omitBy from 'lodash/omitBy';
import qs from 'qs';
import { ndType } from './navidrome-types';
import { resultWithHeaders } from '/@/renderer/api/utils';
import { toast } from '/@/renderer/components';
import { toast } from '/@/renderer/components/toast/index';
import { useAuthStore } from '/@/renderer/store';
import { ServerListItem } from '/@/renderer/types';
@ -186,9 +186,12 @@ axiosClient.interceptors.response.use(
message: 'Your session has expired.',
});
const serverId = useAuthStore.getState().currentServer?.id;
const currentServer = useAuthStore.getState().currentServer;
if (serverId) {
if (currentServer) {
const serverId = currentServer.id;
const token = currentServer.ndCredential;
console.log(`token is expired: ${token}`);
useAuthStore.getState().actions.setCurrentServer(null);
useAuthStore.getState().actions.updateServer(serverId, { ndCredential: undefined });
}
@ -211,7 +214,7 @@ const parsePath = (fullPath: string) => {
};
export const ndApiClient = (args: {
server?: ServerListItem;
server: ServerListItem | null;
signal?: AbortSignal;
url?: string;
}) => {

View File

@ -49,7 +49,7 @@ const authenticate = async (
): Promise<AuthenticationResponse> => {
const cleanServerUrl = url.replace(/\/$/, '');
const res = await ndApiClient({ url: cleanServerUrl }).authenticate({
const res = await ndApiClient({ server: null, url: cleanServerUrl }).authenticate({
body: {
password: body.password,
username: body.username,
@ -148,10 +148,6 @@ const getAlbumArtistList = async (args: AlbumArtistListArgs): Promise<AlbumArtis
throw new Error('Failed to get album artist list');
}
if (!apiClientProps.server) {
throw new Error('Server is required');
}
return {
items: res.body.data.map((albumArtist) =>
ndNormalize.albumArtist(albumArtist, apiClientProps.server),
@ -219,8 +215,6 @@ const getAlbumList = async (args: AlbumListArgs): Promise<AlbumListResponse> =>
const getSongList = async (args: SongListArgs): Promise<SongListResponse> => {
const { query, apiClientProps } = args;
console.log('query :>> ', query);
const res = await ndApiClient(apiClientProps).getSongList({
query: {
_end: query.startIndex + (query.limit || -1),
@ -278,7 +272,9 @@ const createPlaylist = async (args: CreatePlaylistArgs): Promise<CreatePlaylistR
throw new Error('Failed to create playlist');
}
return null;
return {
id: res.body.data.id,
};
};
const updatePlaylist = async (args: UpdatePlaylistArgs): Promise<UpdatePlaylistResponse> => {

View File

@ -5,9 +5,9 @@ import z from 'zod';
import { ndType } from './navidrome-types';
const getCoverArtUrl = (args: {
baseUrl: string;
baseUrl: string | undefined;
coverArtId: string;
credential: string;
credential: string | undefined;
size: number;
}) => {
const size = args.size ? args.size : 250;
@ -28,7 +28,7 @@ const getCoverArtUrl = (args: {
const normalizeSong = (
item: z.infer<typeof ndType._response.song> | z.infer<typeof ndType._response.playlistSong>,
server: ServerListItem,
server: ServerListItem | null,
deviceId: string,
imageSize?: number,
): Song => {
@ -44,9 +44,9 @@ const normalizeSong = (
}
const imageUrl = getCoverArtUrl({
baseUrl: server.url,
baseUrl: server?.url,
coverArtId: id,
credential: server.credential,
credential: server?.credential,
size: imageSize || 100,
});
@ -79,10 +79,10 @@ const normalizeSong = (
playlistItemId,
releaseDate: new Date(item.year, 0, 1).toISOString(),
releaseYear: String(item.year),
serverId: server.id,
serverId: server?.id || 'unknown',
serverType: ServerType.NAVIDROME,
size: item.size,
streamUrl: `${server.url}/rest/stream.view?id=${id}&v=1.13.0&c=feishin_${deviceId}&${server.credential}`,
streamUrl: `${server?.url}/rest/stream.view?id=${id}&v=1.13.0&c=feishin_${deviceId}&${server?.credential}`,
trackNumber: item.trackNumber,
uniqueId: nanoid(),
updatedAt: item.updatedAt,
@ -95,13 +95,13 @@ const normalizeAlbum = (
item: z.infer<typeof ndType._response.album> & {
songs?: z.infer<typeof ndType._response.songList>;
},
server: ServerListItem,
server: ServerListItem | null,
imageSize?: number,
): Album => {
const imageUrl = getCoverArtUrl({
baseUrl: server.url,
baseUrl: server?.url,
coverArtId: item.coverArtId || item.id,
credential: server.credential,
credential: server?.credential,
size: imageSize || 300,
});
@ -126,7 +126,7 @@ const normalizeAlbum = (
playCount: item.playCount,
releaseDate: new Date(item.minYear, 0, 1).toISOString(),
releaseYear: item.minYear,
serverId: server.id,
serverId: server?.id || 'unknown',
serverType: ServerType.NAVIDROME,
size: item.size,
songCount: item.songCount,
@ -140,7 +140,7 @@ const normalizeAlbum = (
const normalizeAlbumArtist = (
item: z.infer<typeof ndType._response.albumArtist>,
server: ServerListItem,
server: ServerListItem | null,
): AlbumArtist => {
const imageUrl =
item.largeImageUrl === '/app/artist-placeholder.webp' ? null : item.largeImageUrl;
@ -157,7 +157,7 @@ const normalizeAlbumArtist = (
lastPlayedAt: item.playDate.includes('0001-') ? null : item.playDate,
name: item.name,
playCount: item.playCount,
serverId: server.id,
serverId: server?.id || 'unknown',
serverType: ServerType.NAVIDROME,
similarArtists: null,
// similarArtists:
@ -174,13 +174,13 @@ const normalizeAlbumArtist = (
const normalizePlaylist = (
item: z.infer<typeof ndType._response.playlist>,
server: ServerListItem,
server: ServerListItem | null,
imageSize?: number,
): Playlist => {
const imageUrl = getCoverArtUrl({
baseUrl: server.url,
baseUrl: server?.url,
coverArtId: item.id,
credential: server.credential,
credential: server?.credential,
size: imageSize || 300,
});
@ -199,7 +199,7 @@ const normalizePlaylist = (
ownerId: item.ownerId,
public: item.public,
rules: item?.rules || null,
serverId: server.id,
serverId: server?.id || 'unknown',
serverType: ServerType.NAVIDROME,
size: item.size,
songCount: item.songCount,

View File

@ -1,8 +1,9 @@
import { initClient, initContract } from '@ts-rest/core';
import axios, { Method, AxiosError, isAxiosError, AxiosResponse } from 'axios';
import { z } from 'zod';
import { ssType } from '/@/renderer/api/subsonic/subsonic-types';
import { ServerListItem } from '/@/renderer/api/types';
import { toast } from '/@/renderer/components';
import { toast } from '/@/renderer/components/toast/index';
const c = initContract();
@ -88,7 +89,7 @@ axiosClient.interceptors.response.use(
}
}
return data['subsonic-response'];
return response;
},
(error) => {
return Promise.reject(error);
@ -96,7 +97,7 @@ axiosClient.interceptors.response.use(
);
export const ssApiClient = (args: {
server?: ServerListItem;
server: ServerListItem | null;
signal?: AbortSignal;
url?: string;
}) => {
@ -124,7 +125,7 @@ export const ssApiClient = (args: {
}
try {
const result = await axiosClient.request({
const result = await axiosClient.request<z.infer<typeof ssType._response.baseResponse>>({
data: body,
headers,
method: method as Method,
@ -137,8 +138,9 @@ export const ssApiClient = (args: {
signal,
url: `${baseUrl}/${path}`,
});
return {
body: { data: result.data, headers: result.headers },
body: result.data['subsonic-response'],
status: result.status,
};
} catch (e: Error | AxiosError | any) {
@ -146,7 +148,7 @@ export const ssApiClient = (args: {
const error = e as AxiosError;
const response = error.response as AxiosResponse;
return {
body: { data: response.data, headers: response.headers },
body: response.data,
status: response.status,
};
}

View File

@ -55,7 +55,7 @@ const authenticate = async (
};
}
await ssApiClient({ url: cleanServerUrl }).authenticate({
await ssApiClient({ server: null, url: cleanServerUrl }).authenticate({
query: {
c: 'Feishin',
f: 'json',
@ -261,9 +261,11 @@ const getTopSongList = async (args: TopSongListArgs): Promise<SongListResponse>
}
return {
items: res.body.topSongs.song.map((song) => ssNormalize.song(song, apiClientProps.server, '')),
items:
res.body.topSongs?.song?.map((song) => ssNormalize.song(song, apiClientProps.server, '')) ||
[],
startIndex: 0,
totalRecordCount: res.body.topSongs.song.length || 0,
totalRecordCount: res.body.topSongs?.song?.length || 0,
};
};

View File

@ -5,9 +5,9 @@ import { QueueSong, LibraryItem } from '/@/renderer/api/types';
import { ServerListItem, ServerType } from '/@/renderer/types';
const getCoverArtUrl = (args: {
baseUrl: string;
baseUrl: string | undefined;
coverArtId?: string;
credential: string;
credential: string | undefined;
size: number;
}) => {
const size = args.size ? args.size : 150;
@ -28,18 +28,18 @@ const getCoverArtUrl = (args: {
const normalizeSong = (
item: z.infer<typeof ssType._response.song>,
server: ServerListItem,
server: ServerListItem | null,
deviceId: string,
): QueueSong => {
const imageUrl =
getCoverArtUrl({
baseUrl: server.url,
baseUrl: server?.url,
coverArtId: item.coverArt,
credential: server.credential,
size: 300,
credential: server?.credential,
size: 100,
}) || null;
const streamUrl = `${server.url}/rest/stream.view?id=${item.id}&v=1.13.0&c=feishin_${deviceId}&${server.credential}`;
const streamUrl = `${server?.url}/rest/stream.view?id=${item.id}&v=1.13.0&c=feishin_${deviceId}&${server?.credential}`;
return {
album: item.album || '',
@ -86,7 +86,7 @@ const normalizeSong = (
playCount: item?.playCount || 0,
releaseDate: null,
releaseYear: item.year ? String(item.year) : null,
serverId: server.id,
serverId: server?.id || 'unknown',
serverType: ServerType.SUBSONIC,
size: item.size,
streamUrl,

View File

@ -276,7 +276,7 @@ export type ListSortOrder = NDOrder | JFSortOrder;
type BaseEndpointArgs = {
apiClientProps: {
server: ServerListItem;
server: ServerListItem | null;
signal?: AbortSignal;
};
};
@ -776,7 +776,7 @@ export type RemoveFromPlaylistArgs = {
} & BaseEndpointArgs;
// Create Playlist
export type CreatePlaylistResponse = null | undefined;
export type CreatePlaylistResponse = { id: string } | undefined;
export type CreatePlaylistBody = {
_custom?: {
@ -918,6 +918,8 @@ export type PlaylistSongListArgs = { query: PlaylistSongListQuery } & BaseEndpoi
// Music Folder List
export type MusicFolderListResponse = BasePaginatedResponse<MusicFolder[]>;
export type MusicFolderListQuery = null;
export type MusicFolderListArgs = BaseEndpointArgs;
// User list