mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-07 20:40:15 +02:00
add new api controller, rework and rename types
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
import { adapter as subsonicAdapter } from './subsonic/subsonic-controller';
|
||||
|
||||
import i18n from '/@/i18n/i18n';
|
||||
import { ApiController } from '/@/shared/types/adapter/api-controller-types';
|
||||
import { ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||
|
||||
interface ApiControllerOptions {
|
||||
type: ServerType;
|
||||
}
|
||||
|
||||
const adapters = {
|
||||
[ServerType.JELLYFIN]: {},
|
||||
[ServerType.NAVIDROME]: {},
|
||||
[ServerType.SUBSONIC]: subsonicAdapter,
|
||||
} as Record<ServerType, ApiController>;
|
||||
|
||||
export const apiController = (options: ApiControllerOptions): ApiController => {
|
||||
const { type } = options;
|
||||
|
||||
const adapter = adapters[type];
|
||||
|
||||
if (!adapter) {
|
||||
throw new Error(i18n.t('error.apiRouteError', { postProcess: 'sentenceCase' }));
|
||||
}
|
||||
|
||||
return adapter;
|
||||
};
|
||||
@@ -1,99 +1,89 @@
|
||||
import {
|
||||
AlbumDetailArgs,
|
||||
AlbumDetailRequest,
|
||||
AlbumDetailResponse,
|
||||
AlbumInfo,
|
||||
AlbumListArgs,
|
||||
AlbumListRequest,
|
||||
AlbumListResponse,
|
||||
} from '/@/shared/types/domain/album-domain-types';
|
||||
import { BaseEndpointArgs } from '/@/shared/types/domain/api-domain-types';
|
||||
import {
|
||||
AlbumArtistDetailArgs,
|
||||
AlbumArtistDetailRequest,
|
||||
AlbumArtistDetailResponse,
|
||||
AlbumArtistListArgs,
|
||||
AlbumArtistListRequest,
|
||||
AlbumArtistListResponse,
|
||||
ArtistListArgs,
|
||||
ArtistListRequest,
|
||||
ArtistListResponse,
|
||||
} from '/@/shared/types/domain/artist-domain-types';
|
||||
import { AuthenticationResponse } from '/@/shared/types/domain/auth-domain-types';
|
||||
import { GenreListArgs, GenreListResponse } from '/@/shared/types/domain/genre-domain-types';
|
||||
import { GenreListRequest, GenreListResponse } from '/@/shared/types/domain/genre-domain-types';
|
||||
import {
|
||||
LyricsArgs,
|
||||
LyricsRequest,
|
||||
LyricsResponse,
|
||||
StructuredLyric,
|
||||
StructuredLyricsArgs,
|
||||
StructuredLyricsRequest,
|
||||
} from '/@/shared/types/domain/lyric-domain-types';
|
||||
import { TranscodingArgs } from '/@/shared/types/domain/player-domain-types';
|
||||
import { TranscodingRequest } from '/@/shared/types/domain/player-domain-types';
|
||||
import {
|
||||
AddToPlaylistArgs,
|
||||
AddToPlaylistResponse,
|
||||
CreatePlaylistArgs,
|
||||
CreatePlaylistRequest,
|
||||
CreatePlaylistResponse,
|
||||
DeletePlaylistArgs,
|
||||
DeletePlaylistRequest,
|
||||
DeletePlaylistResponse,
|
||||
MoveItemArgs,
|
||||
PlaylistDetailArgs,
|
||||
MoveItemRequest,
|
||||
PlaylistDetailRequest,
|
||||
PlaylistDetailResponse,
|
||||
PlaylistListArgs,
|
||||
PlaylistListRequest,
|
||||
PlaylistListResponse,
|
||||
PlaylistSongListArgs,
|
||||
RemoveFromPlaylistArgs,
|
||||
PlaylistSongListRequest,
|
||||
RemoveFromPlaylistRequest,
|
||||
RemoveFromPlaylistResponse,
|
||||
UpdatePlaylistArgs,
|
||||
UpdatePlaylistRequest,
|
||||
UpdatePlaylistResponse,
|
||||
} from '/@/shared/types/domain/playlist-domain-types';
|
||||
import { SearchArgs, SearchResponse } from '/@/shared/types/domain/search-domain-types';
|
||||
import { SearchRequest, SearchResponse } from '/@/shared/types/domain/search-domain-types';
|
||||
import {
|
||||
ServerInfo,
|
||||
ServerInfoArgs,
|
||||
ServerInfoRequest,
|
||||
ServerListItem,
|
||||
ServerMusicFolderListArgs,
|
||||
ServerMusicFolderListRequest,
|
||||
ServerMusicFolderListResponse,
|
||||
ServerType,
|
||||
} from '/@/shared/types/domain/server-domain-types';
|
||||
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||
import { LibraryItem, ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||
import {
|
||||
RandomSongListArgs,
|
||||
SimilarSongsArgs,
|
||||
RandomSongListRequest,
|
||||
SimilarSongsRequest,
|
||||
Song,
|
||||
SongDetailArgs,
|
||||
SongDetailRequest,
|
||||
SongDetailResponse,
|
||||
SongListArgs,
|
||||
SongListRequest,
|
||||
SongListResponse,
|
||||
TopSongListArgs,
|
||||
TopSongListRequest,
|
||||
TopSongListResponse,
|
||||
} from '/@/shared/types/domain/song-domain-types';
|
||||
import { TagArgs, TagsResponse } from '/@/shared/types/domain/tag-domain-types';
|
||||
import { TagRequest, TagsResponse } from '/@/shared/types/domain/tag-domain-types';
|
||||
import {
|
||||
DownloadArgs,
|
||||
FavoriteArgs,
|
||||
DownloadRequest,
|
||||
FavoriteRequest,
|
||||
FavoriteResponse,
|
||||
RatingResponse,
|
||||
ScrobbleArgs,
|
||||
ScrobbleRequest,
|
||||
ScrobbleResponse,
|
||||
SetRatingArgs,
|
||||
ShareItemArgs,
|
||||
SetRatingRequest,
|
||||
ShareItemRequest,
|
||||
ShareItemResponse,
|
||||
UserListArgs,
|
||||
UserListRequest,
|
||||
UserListResponse,
|
||||
} from '/@/shared/types/domain/user-domain-types';
|
||||
|
||||
export interface AdapterError {
|
||||
code: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export type AdapterFn<TRequest, TResponse> = (
|
||||
request: TRequest,
|
||||
server: ServerListItem,
|
||||
options?: AdapterRequestOptions,
|
||||
) => Promise<[AdapterError, null] | [null, TResponse]>;
|
||||
|
||||
export interface AdapterRequestOptions {
|
||||
export type ApiClientProps = {
|
||||
baseUrl?: string;
|
||||
cache?: 'default' | 'force-cache' | 'no-cache' | 'no-store' | 'only-if-cached' | 'reload';
|
||||
credentials?: 'include' | 'omit' | 'same-origin';
|
||||
integrity?: string;
|
||||
keepalive?: boolean;
|
||||
mode?: 'cors' | 'navigate' | 'no-cors' | 'same-origin';
|
||||
parseAs?: 'arrayBuffer' | 'blob' | 'json' | 'text';
|
||||
priority?: 'auto' | 'high' | 'low';
|
||||
redirect?: 'error' | 'follow' | 'manual';
|
||||
referrer?: string;
|
||||
@@ -108,86 +98,116 @@ export interface AdapterRequestOptions {
|
||||
| 'strict-origin-when-cross-origin'
|
||||
| 'unsafe-url';
|
||||
signal?: AbortSignal | null;
|
||||
window?: null;
|
||||
}
|
||||
};
|
||||
|
||||
export type ControllerEndpoint = {
|
||||
export type ApiController = {
|
||||
_utility: {
|
||||
getDownloadUrl: ApiControllerFn<DownloadRequest, string>;
|
||||
getImageUrl: (
|
||||
args: { id: string; size?: number; type: LibraryItem },
|
||||
server: ServerListItem,
|
||||
) => string;
|
||||
getStreamUrl: (
|
||||
args: { bitRate?: number; format?: string; id: string },
|
||||
server: ServerListItem,
|
||||
) => string;
|
||||
};
|
||||
album: {
|
||||
getDetail: (args: AlbumDetailArgs) => Promise<AlbumDetailResponse>;
|
||||
getInfo?: (args: AlbumDetailArgs) => Promise<AlbumInfo>;
|
||||
getList: (args: AlbumListArgs) => Promise<AlbumListResponse>;
|
||||
getListCount: (args: AlbumListArgs) => Promise<number>;
|
||||
getDetail: ApiControllerFn<AlbumDetailRequest, AlbumDetailResponse>;
|
||||
getInfo?: ApiControllerFn<AlbumDetailRequest, AlbumInfo>;
|
||||
getList: ApiControllerFn<AlbumListRequest, AlbumListResponse>;
|
||||
getListCount: ApiControllerFn<AlbumListRequest, number>;
|
||||
};
|
||||
albumArtist: {
|
||||
getDetail: (args: AlbumArtistDetailArgs) => Promise<AlbumArtistDetailResponse>;
|
||||
getList: (args: AlbumArtistListArgs) => Promise<AlbumArtistListResponse>;
|
||||
getListCount: (args: AlbumArtistListArgs) => Promise<number>;
|
||||
getDetail: ApiControllerFn<AlbumArtistDetailRequest, AlbumArtistDetailResponse>;
|
||||
getList: ApiControllerFn<AlbumArtistListRequest, AlbumArtistListResponse>;
|
||||
getListCount: ApiControllerFn<AlbumArtistListRequest, number>;
|
||||
};
|
||||
artist: {
|
||||
getList: (args: ArtistListArgs) => Promise<ArtistListResponse>;
|
||||
getListCount: (args: ArtistListArgs) => Promise<number>;
|
||||
getList: ApiControllerFn<ArtistListRequest, ArtistListResponse>;
|
||||
getListCount: ApiControllerFn<ArtistListRequest, number>;
|
||||
};
|
||||
favorite: {
|
||||
create: (args: FavoriteArgs) => Promise<FavoriteResponse>;
|
||||
delete: (args: FavoriteArgs) => Promise<FavoriteResponse>;
|
||||
create: ApiControllerFn<FavoriteRequest, FavoriteResponse>;
|
||||
delete: ApiControllerFn<FavoriteRequest, FavoriteResponse>;
|
||||
};
|
||||
genre: {
|
||||
getList: (args: GenreListArgs) => Promise<GenreListResponse>;
|
||||
getList: ApiControllerFn<GenreListRequest, GenreListResponse>;
|
||||
};
|
||||
musicFolder: {
|
||||
getList: (args: ServerMusicFolderListArgs) => Promise<ServerMusicFolderListResponse>;
|
||||
getList: ApiControllerFn<ServerMusicFolderListRequest, ServerMusicFolderListResponse>;
|
||||
};
|
||||
playlist: {
|
||||
addTo: (args: AddToPlaylistArgs) => Promise<AddToPlaylistResponse>;
|
||||
create: (args: CreatePlaylistArgs) => Promise<CreatePlaylistResponse>;
|
||||
delete: (args: DeletePlaylistArgs) => Promise<DeletePlaylistResponse>;
|
||||
getDetail: (args: PlaylistDetailArgs) => Promise<PlaylistDetailResponse>;
|
||||
getList: (args: PlaylistListArgs) => Promise<PlaylistListResponse>;
|
||||
getListCount: (args: PlaylistListArgs) => Promise<number>;
|
||||
getSongList: (args: PlaylistSongListArgs) => Promise<SongListResponse>;
|
||||
moveItem?: (args: MoveItemArgs) => Promise<void>;
|
||||
removeFrom: (args: RemoveFromPlaylistArgs) => Promise<RemoveFromPlaylistResponse>;
|
||||
update: (args: UpdatePlaylistArgs) => Promise<UpdatePlaylistResponse>;
|
||||
addTo: ApiControllerFn<AddToPlaylistArgs, AddToPlaylistResponse>;
|
||||
create: ApiControllerFn<CreatePlaylistRequest, CreatePlaylistResponse>;
|
||||
delete: ApiControllerFn<DeletePlaylistRequest, DeletePlaylistResponse>;
|
||||
getDetail: ApiControllerFn<PlaylistDetailRequest, PlaylistDetailResponse>;
|
||||
getList: ApiControllerFn<PlaylistListRequest, PlaylistListResponse>;
|
||||
getListCount: ApiControllerFn<PlaylistListRequest, number>;
|
||||
getSongList: ApiControllerFn<PlaylistSongListRequest, SongListResponse>;
|
||||
moveItem?: ApiControllerFn<MoveItemRequest, void>;
|
||||
removeFrom: ApiControllerFn<RemoveFromPlaylistRequest, RemoveFromPlaylistResponse>;
|
||||
update: ApiControllerFn<UpdatePlaylistRequest, UpdatePlaylistResponse>;
|
||||
};
|
||||
server: {
|
||||
authenticate: (
|
||||
url: string,
|
||||
body: { legacy?: boolean; password: string; username: string },
|
||||
) => Promise<AuthenticationResponse>;
|
||||
getCoverArtUrl: (
|
||||
args: { id: string; size?: number; type: LibraryItem },
|
||||
server: ServerListItem,
|
||||
) => string;
|
||||
getRoles: (
|
||||
args: BaseEndpointArgs,
|
||||
) => Promise<Array<string | { label: string; value: string }>>;
|
||||
getServerInfo: (args: ServerInfoArgs) => Promise<ServerInfo>;
|
||||
getStreamUrl: (
|
||||
args: { bitRate?: number; format?: string; id: string },
|
||||
server: ServerListItem,
|
||||
) => string;
|
||||
getTags: (args: TagArgs) => Promise<TagsResponse>;
|
||||
getTranscodingUrl: (args: TranscodingArgs) => string;
|
||||
getRoles: ApiControllerFn<
|
||||
BaseEndpointArgs,
|
||||
Array<string | { label: string; value: string }>
|
||||
>;
|
||||
getServerInfo: ApiControllerFn<ServerInfoRequest, ServerInfo>;
|
||||
getTags: ApiControllerFn<TagRequest, TagsResponse>;
|
||||
getTranscodingUrl: ApiControllerFn<TranscodingRequest, string>;
|
||||
getType: () => ServerType;
|
||||
scrobble: (args: ScrobbleArgs) => Promise<ScrobbleResponse>;
|
||||
search: (args: SearchArgs) => Promise<SearchResponse>;
|
||||
scrobble: ApiControllerFn<ScrobbleRequest, ScrobbleResponse>;
|
||||
search: ApiControllerFn<SearchRequest, SearchResponse>;
|
||||
};
|
||||
song: {
|
||||
getDetail: (args: SongDetailArgs) => Promise<SongDetailResponse>;
|
||||
getDownloadUrl: (args: DownloadArgs) => string;
|
||||
getList: (args: SongListArgs) => Promise<SongListResponse>;
|
||||
getListCount: (args: SongListArgs) => Promise<number>;
|
||||
getLyrics?: (args: LyricsArgs) => Promise<LyricsResponse>;
|
||||
getRandomList: (args: RandomSongListArgs) => Promise<SongListResponse>;
|
||||
getSimilar: (args: SimilarSongsArgs) => Promise<Song[]>;
|
||||
getStructuredLyrics?: (args: StructuredLyricsArgs) => Promise<StructuredLyric[]>;
|
||||
getTopList: (args: TopSongListArgs) => Promise<TopSongListResponse>;
|
||||
getDetail: ApiControllerFn<SongDetailRequest, SongDetailResponse>;
|
||||
getList: ApiControllerFn<SongListRequest, SongListResponse>;
|
||||
getListCount: ApiControllerFn<SongListRequest, number>;
|
||||
getLyrics?: ApiControllerFn<LyricsRequest, LyricsResponse>;
|
||||
getRandomList: ApiControllerFn<RandomSongListRequest, SongListResponse>;
|
||||
getSimilar: ApiControllerFn<SimilarSongsRequest, Song[]>;
|
||||
getStructuredLyrics?: ApiControllerFn<StructuredLyricsRequest, StructuredLyric[]>;
|
||||
getTopList: ApiControllerFn<TopSongListRequest, TopSongListResponse>;
|
||||
};
|
||||
user: {
|
||||
getList?: (args: UserListArgs) => Promise<UserListResponse>;
|
||||
setRating?: (args: SetRatingArgs) => Promise<RatingResponse>;
|
||||
shareItem?: (args: ShareItemArgs) => Promise<ShareItemResponse>;
|
||||
getList?: ApiControllerFn<UserListRequest, UserListResponse>;
|
||||
setRating?: ApiControllerFn<SetRatingRequest, RatingResponse>;
|
||||
shareItem?: ApiControllerFn<ShareItemRequest, ShareItemResponse>;
|
||||
};
|
||||
};
|
||||
|
||||
export type ExtractAdapterResponse<T> = T extends AdapterFn<any, infer R> ? R : never;
|
||||
export interface ApiControllerError {
|
||||
code: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export type ApiControllerFn<TRequest, TResponse> = (
|
||||
request: TRequest,
|
||||
server: ServerListItem,
|
||||
options?: ApiClientProps,
|
||||
) => Promise<[ApiControllerError, null] | [null, TResponse]>;
|
||||
|
||||
export type BaseEndpointArgs = {
|
||||
apiClientProps: {
|
||||
signal?: AbortSignal;
|
||||
};
|
||||
};
|
||||
export interface BasePaginatedResponse<T> {
|
||||
error?: any | string;
|
||||
items: T;
|
||||
startIndex: number;
|
||||
totalRecordCount: null | number;
|
||||
}
|
||||
|
||||
export interface BaseQuery<T> {
|
||||
sortBy: T;
|
||||
sortOrder: ListSortOrder;
|
||||
}
|
||||
|
||||
export type ExtractControllerResponse<T> = T extends ApiControllerFn<any, infer R> ? R : never;
|
||||
|
||||
@@ -6,11 +6,7 @@ import { JFAlbumListSort } from '/@/shared/api/jellyfin.types';
|
||||
import { jfType } from '/@/shared/api/jellyfin/jellyfin-types';
|
||||
import { NDAlbumListSort } from '/@/shared/api/navidrome.types';
|
||||
import { ndType } from '/@/shared/api/navidrome/navidrome-types';
|
||||
import {
|
||||
BaseEndpointArgs,
|
||||
BasePaginatedResponse,
|
||||
BaseQuery,
|
||||
} from '/@/shared/types/domain/api-domain-types';
|
||||
import { BasePaginatedResponse, BaseQuery } from '/@/shared/types/adapter/api-controller-types';
|
||||
import { RelatedArtist } from '/@/shared/types/domain/artist-domain-types';
|
||||
import { Genre } from '/@/shared/types/domain/genre-domain-types';
|
||||
import { ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||
@@ -71,8 +67,6 @@ export enum AlbumListSort {
|
||||
YEAR = 'year',
|
||||
}
|
||||
|
||||
export type AlbumListArgs = BaseEndpointArgs & { query: AlbumListQuery };
|
||||
|
||||
export interface AlbumListQuery extends BaseQuery<AlbumListSort> {
|
||||
_custom?: {
|
||||
jellyfin?: Partial<z.infer<typeof jfType._parameters.albumList>>;
|
||||
@@ -90,7 +84,10 @@ export interface AlbumListQuery extends BaseQuery<AlbumListSort> {
|
||||
startIndex: number;
|
||||
}
|
||||
|
||||
export type AlbumListRequest = { query: AlbumListQuery };
|
||||
|
||||
export type AlbumListResponse = BasePaginatedResponse<Album[]> | null | undefined;
|
||||
|
||||
type AlbumListSortMap = {
|
||||
jellyfin: Record<AlbumListSort, JFAlbumListSort | undefined>;
|
||||
navidrome: Record<AlbumListSort, NDAlbumListSort | undefined>;
|
||||
@@ -200,10 +197,10 @@ export type Album = {
|
||||
userRating: null | number;
|
||||
} & { songs?: Song[] };
|
||||
|
||||
export type AlbumDetailArgs = BaseEndpointArgs & { query: AlbumDetailQuery };
|
||||
|
||||
export type AlbumDetailQuery = { id: string };
|
||||
|
||||
export type AlbumDetailRequest = { query: AlbumDetailQuery };
|
||||
|
||||
export type AlbumDetailResponse = Album | null | undefined;
|
||||
|
||||
export type AlbumInfo = {
|
||||
|
||||
@@ -1,103 +1,79 @@
|
||||
import { BaseEndpointArgs } from '/@/shared/types/adapter/api-controller-types';
|
||||
import {
|
||||
AlbumDetailArgs,
|
||||
AlbumDetailRequest,
|
||||
AlbumDetailResponse,
|
||||
AlbumInfo,
|
||||
AlbumListArgs,
|
||||
AlbumListRequest,
|
||||
AlbumListResponse,
|
||||
} from '/@/shared/types/domain/album-domain-types';
|
||||
import {
|
||||
AlbumArtistDetailArgs,
|
||||
AlbumArtistDetailRequest,
|
||||
AlbumArtistDetailResponse,
|
||||
AlbumArtistListArgs,
|
||||
AlbumArtistListRequest,
|
||||
AlbumArtistListResponse,
|
||||
ArtistListArgs,
|
||||
ArtistListRequest,
|
||||
ArtistListResponse,
|
||||
} from '/@/shared/types/domain/artist-domain-types';
|
||||
import { AuthenticationResponse } from '/@/shared/types/domain/auth-domain-types';
|
||||
import { GenreListArgs, GenreListResponse } from '/@/shared/types/domain/genre-domain-types';
|
||||
import { GenreListRequest, GenreListResponse } from '/@/shared/types/domain/genre-domain-types';
|
||||
import {
|
||||
LyricsArgs,
|
||||
LyricsRequest,
|
||||
LyricsResponse,
|
||||
StructuredLyric,
|
||||
StructuredLyricsArgs,
|
||||
StructuredLyricsRequest,
|
||||
} from '/@/shared/types/domain/lyric-domain-types';
|
||||
import { TranscodingArgs } from '/@/shared/types/domain/player-domain-types';
|
||||
import { TranscodingRequest } from '/@/shared/types/domain/player-domain-types';
|
||||
import {
|
||||
AddToPlaylistArgs,
|
||||
AddToPlaylistResponse,
|
||||
CreatePlaylistArgs,
|
||||
CreatePlaylistRequest,
|
||||
CreatePlaylistResponse,
|
||||
DeletePlaylistArgs,
|
||||
DeletePlaylistRequest,
|
||||
DeletePlaylistResponse,
|
||||
MoveItemArgs,
|
||||
PlaylistDetailArgs,
|
||||
MoveItemRequest,
|
||||
PlaylistDetailRequest,
|
||||
PlaylistDetailResponse,
|
||||
PlaylistListArgs,
|
||||
PlaylistListRequest,
|
||||
PlaylistListResponse,
|
||||
PlaylistSongListArgs,
|
||||
RemoveFromPlaylistArgs,
|
||||
PlaylistSongListRequest,
|
||||
RemoveFromPlaylistRequest,
|
||||
RemoveFromPlaylistResponse,
|
||||
UpdatePlaylistArgs,
|
||||
UpdatePlaylistRequest,
|
||||
UpdatePlaylistResponse,
|
||||
} from '/@/shared/types/domain/playlist-domain-types';
|
||||
import { SearchArgs, SearchResponse } from '/@/shared/types/domain/search-domain-types';
|
||||
import { SearchRequest, SearchResponse } from '/@/shared/types/domain/search-domain-types';
|
||||
import {
|
||||
ServerInfo,
|
||||
ServerInfoArgs,
|
||||
ServerListItem,
|
||||
ServerMusicFolderListArgs,
|
||||
ServerInfoRequest,
|
||||
ServerMusicFolderListRequest,
|
||||
ServerMusicFolderListResponse,
|
||||
} from '/@/shared/types/domain/server-domain-types';
|
||||
import { ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||
import {
|
||||
RandomSongListArgs,
|
||||
SimilarSongsArgs,
|
||||
RandomSongListRequest,
|
||||
SimilarSongsRequest,
|
||||
Song,
|
||||
SongDetailArgs,
|
||||
SongDetailRequest,
|
||||
SongDetailResponse,
|
||||
SongListArgs,
|
||||
SongListRequest,
|
||||
SongListResponse,
|
||||
TopSongListArgs,
|
||||
TopSongListRequest,
|
||||
TopSongListResponse,
|
||||
} from '/@/shared/types/domain/song-domain-types';
|
||||
import { TagArgs, TagsResponse } from '/@/shared/types/domain/tag-domain-types';
|
||||
import { TagRequest, TagsResponse } from '/@/shared/types/domain/tag-domain-types';
|
||||
import {
|
||||
DownloadArgs,
|
||||
FavoriteArgs,
|
||||
DownloadRequest,
|
||||
FavoriteRequest,
|
||||
FavoriteResponse,
|
||||
RatingResponse,
|
||||
ScrobbleArgs,
|
||||
ScrobbleRequest,
|
||||
ScrobbleResponse,
|
||||
SetRatingArgs,
|
||||
ShareItemArgs,
|
||||
SetRatingRequest,
|
||||
ShareItemRequest,
|
||||
ShareItemResponse,
|
||||
UserListArgs,
|
||||
UserListRequest,
|
||||
UserListResponse,
|
||||
} from '/@/shared/types/domain/user-domain-types';
|
||||
|
||||
export type BaseEndpointArgs = {
|
||||
apiClientProps: {
|
||||
server: null | ServerListItem;
|
||||
signal?: AbortSignal;
|
||||
};
|
||||
};
|
||||
|
||||
export interface BasePaginatedResponse<T> {
|
||||
error?: any | string;
|
||||
items: T;
|
||||
startIndex: number;
|
||||
totalRecordCount: null | number;
|
||||
}
|
||||
|
||||
export interface BaseQuery<T> {
|
||||
sortBy: T;
|
||||
sortOrder: ListSortOrder;
|
||||
}
|
||||
|
||||
export type EndpointDetails = {
|
||||
server: ServerListItem;
|
||||
};
|
||||
|
||||
export const instanceOfCancellationError = (error: any) => {
|
||||
return 'revert' in error;
|
||||
};
|
||||
@@ -108,44 +84,46 @@ export type ControllerEndpoint = {
|
||||
url: string,
|
||||
body: { legacy?: boolean; password: string; username: string },
|
||||
) => Promise<AuthenticationResponse>;
|
||||
createFavorite: (args: FavoriteArgs) => Promise<FavoriteResponse>;
|
||||
createPlaylist: (args: CreatePlaylistArgs) => Promise<CreatePlaylistResponse>;
|
||||
deleteFavorite: (args: FavoriteArgs) => Promise<FavoriteResponse>;
|
||||
deletePlaylist: (args: DeletePlaylistArgs) => Promise<DeletePlaylistResponse>;
|
||||
getAlbumArtistDetail: (args: AlbumArtistDetailArgs) => Promise<AlbumArtistDetailResponse>;
|
||||
getAlbumArtistList: (args: AlbumArtistListArgs) => Promise<AlbumArtistListResponse>;
|
||||
getAlbumArtistListCount: (args: AlbumArtistListArgs) => Promise<number>;
|
||||
getAlbumDetail: (args: AlbumDetailArgs) => Promise<AlbumDetailResponse>;
|
||||
getAlbumInfo?: (args: AlbumDetailArgs) => Promise<AlbumInfo>;
|
||||
getAlbumList: (args: AlbumListArgs) => Promise<AlbumListResponse>;
|
||||
getAlbumListCount: (args: AlbumListArgs) => Promise<number>;
|
||||
getArtistList: (args: ArtistListArgs) => Promise<ArtistListResponse>;
|
||||
getArtistListCount: (args: ArtistListArgs) => Promise<number>;
|
||||
getDownloadUrl: (args: DownloadArgs) => string;
|
||||
getGenreList: (args: GenreListArgs) => Promise<GenreListResponse>;
|
||||
getLyrics?: (args: LyricsArgs) => Promise<LyricsResponse>;
|
||||
getMusicFolderList: (args: ServerMusicFolderListArgs) => Promise<ServerMusicFolderListResponse>;
|
||||
getPlaylistDetail: (args: PlaylistDetailArgs) => Promise<PlaylistDetailResponse>;
|
||||
getPlaylistList: (args: PlaylistListArgs) => Promise<PlaylistListResponse>;
|
||||
getPlaylistListCount: (args: PlaylistListArgs) => Promise<number>;
|
||||
getPlaylistSongList: (args: PlaylistSongListArgs) => Promise<SongListResponse>;
|
||||
getRandomSongList: (args: RandomSongListArgs) => Promise<SongListResponse>;
|
||||
createFavorite: (args: FavoriteRequest) => Promise<FavoriteResponse>;
|
||||
createPlaylist: (args: CreatePlaylistRequest) => Promise<CreatePlaylistResponse>;
|
||||
deleteFavorite: (args: FavoriteRequest) => Promise<FavoriteResponse>;
|
||||
deletePlaylist: (args: DeletePlaylistRequest) => Promise<DeletePlaylistResponse>;
|
||||
getAlbumArtistDetail: (args: AlbumArtistDetailRequest) => Promise<AlbumArtistDetailResponse>;
|
||||
getAlbumArtistList: (args: AlbumArtistListRequest) => Promise<AlbumArtistListResponse>;
|
||||
getAlbumArtistListCount: (args: AlbumArtistListRequest) => Promise<number>;
|
||||
getAlbumDetail: (args: AlbumDetailRequest) => Promise<AlbumDetailResponse>;
|
||||
getAlbumInfo?: (args: AlbumDetailRequest) => Promise<AlbumInfo>;
|
||||
getAlbumList: (args: AlbumListRequest) => Promise<AlbumListResponse>;
|
||||
getAlbumListCount: (args: AlbumListRequest) => Promise<number>;
|
||||
getArtistList: (args: ArtistListRequest) => Promise<ArtistListResponse>;
|
||||
getArtistListCount: (args: ArtistListRequest) => Promise<number>;
|
||||
getDownloadUrl: (args: DownloadRequest) => string;
|
||||
getGenreList: (args: GenreListRequest) => Promise<GenreListResponse>;
|
||||
getLyrics?: (args: LyricsRequest) => Promise<LyricsResponse>;
|
||||
getMusicFolderList: (
|
||||
args: ServerMusicFolderListRequest,
|
||||
) => Promise<ServerMusicFolderListResponse>;
|
||||
getPlaylistDetail: (args: PlaylistDetailRequest) => Promise<PlaylistDetailResponse>;
|
||||
getPlaylistList: (args: PlaylistListRequest) => Promise<PlaylistListResponse>;
|
||||
getPlaylistListCount: (args: PlaylistListRequest) => Promise<number>;
|
||||
getPlaylistSongList: (args: PlaylistSongListRequest) => Promise<SongListResponse>;
|
||||
getRandomSongList: (args: RandomSongListRequest) => Promise<SongListResponse>;
|
||||
getRoles: (args: BaseEndpointArgs) => Promise<Array<string | { label: string; value: string }>>;
|
||||
getServerInfo: (args: ServerInfoArgs) => Promise<ServerInfo>;
|
||||
getSimilarSongs: (args: SimilarSongsArgs) => Promise<Song[]>;
|
||||
getSongDetail: (args: SongDetailArgs) => Promise<SongDetailResponse>;
|
||||
getSongList: (args: SongListArgs) => Promise<SongListResponse>;
|
||||
getSongListCount: (args: SongListArgs) => Promise<number>;
|
||||
getStructuredLyrics?: (args: StructuredLyricsArgs) => Promise<StructuredLyric[]>;
|
||||
getTags?: (args: TagArgs) => Promise<TagsResponse>;
|
||||
getTopSongs: (args: TopSongListArgs) => Promise<TopSongListResponse>;
|
||||
getTranscodingUrl: (args: TranscodingArgs) => string;
|
||||
getUserList?: (args: UserListArgs) => Promise<UserListResponse>;
|
||||
movePlaylistItem?: (args: MoveItemArgs) => Promise<void>;
|
||||
removeFromPlaylist: (args: RemoveFromPlaylistArgs) => Promise<RemoveFromPlaylistResponse>;
|
||||
scrobble: (args: ScrobbleArgs) => Promise<ScrobbleResponse>;
|
||||
search: (args: SearchArgs) => Promise<SearchResponse>;
|
||||
setRating?: (args: SetRatingArgs) => Promise<RatingResponse>;
|
||||
shareItem?: (args: ShareItemArgs) => Promise<ShareItemResponse>;
|
||||
updatePlaylist: (args: UpdatePlaylistArgs) => Promise<UpdatePlaylistResponse>;
|
||||
getServerInfo: (args: ServerInfoRequest) => Promise<ServerInfo>;
|
||||
getSimilarSongs: (args: SimilarSongsRequest) => Promise<Song[]>;
|
||||
getSongDetail: (args: SongDetailRequest) => Promise<SongDetailResponse>;
|
||||
getSongList: (args: SongListRequest) => Promise<SongListResponse>;
|
||||
getSongListCount: (args: SongListRequest) => Promise<number>;
|
||||
getStructuredLyrics?: (args: StructuredLyricsRequest) => Promise<StructuredLyric[]>;
|
||||
getTags?: (args: TagRequest) => Promise<TagsResponse>;
|
||||
getTopSongs: (args: TopSongListRequest) => Promise<TopSongListResponse>;
|
||||
getTranscodingUrl: (args: TranscodingRequest) => string;
|
||||
getUserList?: (args: UserListRequest) => Promise<UserListResponse>;
|
||||
movePlaylistItem?: (args: MoveItemRequest) => Promise<void>;
|
||||
removeFromPlaylist: (args: RemoveFromPlaylistRequest) => Promise<RemoveFromPlaylistResponse>;
|
||||
scrobble: (args: ScrobbleRequest) => Promise<ScrobbleResponse>;
|
||||
search: (args: SearchRequest) => Promise<SearchResponse>;
|
||||
setRating?: (args: SetRatingRequest) => Promise<RatingResponse>;
|
||||
shareItem?: (args: ShareItemRequest) => Promise<ShareItemResponse>;
|
||||
updatePlaylist: (args: UpdatePlaylistRequest) => Promise<UpdatePlaylistResponse>;
|
||||
};
|
||||
|
||||
@@ -6,11 +6,7 @@ import { JFAlbumArtistListSort, JFArtistListSort } from '/@/shared/api/jellyfin.
|
||||
import { jfType } from '/@/shared/api/jellyfin/jellyfin-types';
|
||||
import { NDAlbumArtistListSort } from '/@/shared/api/navidrome.types';
|
||||
import { ndType } from '/@/shared/api/navidrome/navidrome-types';
|
||||
import {
|
||||
BaseEndpointArgs,
|
||||
BasePaginatedResponse,
|
||||
BaseQuery,
|
||||
} from '/@/shared/types/domain/api-domain-types';
|
||||
import { BasePaginatedResponse, BaseQuery } from '/@/shared/types/adapter/api-controller-types';
|
||||
import { Genre } from '/@/shared/types/domain/genre-domain-types';
|
||||
import { ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||
import { LibraryItem, ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||
@@ -142,13 +138,11 @@ export enum ArtistListSort {
|
||||
SONG_COUNT = 'songCount',
|
||||
}
|
||||
|
||||
export type AlbumArtistDetailArgs = BaseEndpointArgs & { query: AlbumArtistDetailQuery };
|
||||
|
||||
export type AlbumArtistDetailQuery = { id: string };
|
||||
|
||||
export type AlbumArtistDetailResponse = AlbumArtist | null;
|
||||
export type AlbumArtistDetailRequest = { query: AlbumArtistDetailQuery };
|
||||
|
||||
export type ArtistListArgs = BaseEndpointArgs & { query: ArtistListQuery };
|
||||
export type AlbumArtistDetailResponse = AlbumArtist | null;
|
||||
|
||||
export interface ArtistListQuery extends BaseQuery<ArtistListSort> {
|
||||
_custom?: {
|
||||
@@ -162,6 +156,8 @@ export interface ArtistListQuery extends BaseQuery<ArtistListSort> {
|
||||
startIndex: number;
|
||||
}
|
||||
|
||||
export type ArtistListRequest = { query: ArtistListQuery };
|
||||
|
||||
export type ArtistListResponse = BasePaginatedResponse<AlbumArtist[]> | null | undefined;
|
||||
type ArtistListSortMap = {
|
||||
jellyfin: Record<ArtistListSort, JFArtistListSort | undefined>;
|
||||
@@ -224,8 +220,6 @@ export enum AlbumArtistListSort {
|
||||
SONG_COUNT = 'songCount',
|
||||
}
|
||||
|
||||
export type AlbumArtistListArgs = BaseEndpointArgs & { query: AlbumArtistListQuery };
|
||||
|
||||
export interface AlbumArtistListQuery extends BaseQuery<AlbumArtistListSort> {
|
||||
_custom?: {
|
||||
jellyfin?: Partial<z.infer<typeof jfType._parameters.albumArtistList>>;
|
||||
@@ -236,14 +230,19 @@ export interface AlbumArtistListQuery extends BaseQuery<AlbumArtistListSort> {
|
||||
searchTerm?: string;
|
||||
startIndex: number;
|
||||
}
|
||||
|
||||
export type AlbumArtistListRequest = { query: AlbumArtistListQuery };
|
||||
|
||||
export type AlbumArtistListResponse = BasePaginatedResponse<AlbumArtist[]> | null | undefined;
|
||||
export type ArtistInfoArgs = BaseEndpointArgs & { query: ArtistInfoQuery };
|
||||
|
||||
export type ArtistInfoQuery = {
|
||||
artistId: string;
|
||||
limit: number;
|
||||
musicFolderId?: string;
|
||||
};
|
||||
|
||||
export type ArtistInfoRequest = { query: ArtistInfoQuery };
|
||||
|
||||
export const sortAlbumArtistList = (
|
||||
artists: AlbumArtist[],
|
||||
sortBy: AlbumArtistListSort | ArtistListSort,
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import i18n from '/@/i18n/i18n';
|
||||
import { JFGenreListSort } from '/@/shared/api/jellyfin.types';
|
||||
import { NDGenreListSort } from '/@/shared/api/navidrome.types';
|
||||
import {
|
||||
BaseEndpointArgs,
|
||||
BasePaginatedResponse,
|
||||
BaseQuery,
|
||||
} from '/@/shared/types/domain/api-domain-types';
|
||||
import { BasePaginatedResponse, BaseQuery } from '/@/shared/types/adapter/api-controller-types';
|
||||
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||
import { UserListSort } from '/@/shared/types/domain/user-domain-types';
|
||||
|
||||
@@ -30,8 +26,6 @@ export type Genre = {
|
||||
songCount?: number;
|
||||
};
|
||||
|
||||
export type GenreListArgs = BaseEndpointArgs & { query: GenreListQuery };
|
||||
|
||||
export interface GenreListQuery extends BaseQuery<GenreListSort> {
|
||||
_custom?: {
|
||||
jellyfin?: null;
|
||||
@@ -43,9 +37,10 @@ export interface GenreListQuery extends BaseQuery<GenreListSort> {
|
||||
startIndex: number;
|
||||
}
|
||||
|
||||
export type GenreListRequest = { query: GenreListQuery };
|
||||
|
||||
export type GenreListResponse = BasePaginatedResponse<Genre[]> | null | undefined;
|
||||
|
||||
export type GenresResponse = Genre[];
|
||||
type GenreListSortMap = {
|
||||
jellyfin: Record<GenreListSort, JFGenreListSort | undefined>;
|
||||
navidrome: Record<GenreListSort, NDGenreListSort | undefined>;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { BaseEndpointArgs } from './api-domain-types';
|
||||
import { Song } from '/@/shared/types/domain/song-domain-types';
|
||||
|
||||
export enum LyricSource {
|
||||
@@ -35,9 +34,6 @@ export type LyricGetQuery = {
|
||||
|
||||
export type LyricOverride = Omit<InternetProviderLyricResponse, 'lyrics'>;
|
||||
|
||||
export type LyricsArgs = BaseEndpointArgs & {
|
||||
query: LyricsQuery;
|
||||
};
|
||||
export type LyricSearchQuery = {
|
||||
album?: string;
|
||||
artist?: string;
|
||||
@@ -50,22 +46,26 @@ export type LyricsQuery = {
|
||||
songId: string;
|
||||
};
|
||||
|
||||
export type LyricsRequest = {
|
||||
query: LyricsQuery;
|
||||
};
|
||||
|
||||
export type LyricsResponse = string | SynchronizedLyricsArray;
|
||||
|
||||
export type StructuredLyric = (StructuredSyncedLyric | StructuredUnsyncedLyric) & {
|
||||
lang: string;
|
||||
};
|
||||
|
||||
export type StructuredLyricsArgs = BaseEndpointArgs & {
|
||||
query: LyricsQuery;
|
||||
};
|
||||
export type StructuredLyricsRequest = { query: LyricsQuery };
|
||||
|
||||
export type StructuredSyncedLyric = Omit<FullLyricsMetadata, 'lyrics'> & {
|
||||
lyrics: SynchronizedLyricsArray;
|
||||
synced: true;
|
||||
};
|
||||
|
||||
export type StructuredUnsyncedLyric = Omit<FullLyricsMetadata, 'lyrics'> & {
|
||||
lyrics: string;
|
||||
synced: false;
|
||||
};
|
||||
|
||||
export type SynchronizedLyricsArray = Array<[number, string]>;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { BaseEndpointArgs } from '/@/shared/types/domain/api-domain-types';
|
||||
import { Song } from '/@/shared/types/domain/song-domain-types';
|
||||
import { PlayerStatus } from '/@/shared/types/types';
|
||||
|
||||
@@ -29,15 +28,17 @@ export interface QueueData {
|
||||
next?: QueueSong;
|
||||
previous?: QueueSong;
|
||||
}
|
||||
|
||||
export type QueueSong = Song & {
|
||||
uniqueId: string;
|
||||
};
|
||||
export type TranscodingArgs = BaseEndpointArgs & {
|
||||
query: TranscodingQuery;
|
||||
};
|
||||
|
||||
export type TranscodingQuery = {
|
||||
base: string;
|
||||
bitrate?: number;
|
||||
format?: string;
|
||||
};
|
||||
|
||||
export type TranscodingRequest = {
|
||||
query: TranscodingQuery;
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
BaseEndpointArgs,
|
||||
BasePaginatedResponse,
|
||||
BaseQuery,
|
||||
} from '/@/shared/types/domain/api-domain-types';
|
||||
} from '/@/shared/types/adapter/api-controller-types';
|
||||
import { Genre } from '/@/shared/types/domain/genre-domain-types';
|
||||
import { ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||
import { LibraryItem, ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||
@@ -58,8 +58,6 @@ export type AddToPlaylistQuery = {
|
||||
|
||||
export type AddToPlaylistResponse = null | undefined;
|
||||
|
||||
export type CreatePlaylistArgs = BaseEndpointArgs & { body: CreatePlaylistBody; serverId?: string };
|
||||
|
||||
export type CreatePlaylistBody = {
|
||||
_custom?: {
|
||||
navidrome?: {
|
||||
@@ -74,15 +72,20 @@ export type CreatePlaylistBody = {
|
||||
public?: boolean;
|
||||
};
|
||||
|
||||
export type CreatePlaylistResponse = undefined | { id: string };
|
||||
|
||||
export type DeletePlaylistArgs = BaseEndpointArgs & {
|
||||
query: DeletePlaylistQuery;
|
||||
export type CreatePlaylistRequest = {
|
||||
body: CreatePlaylistBody;
|
||||
serverId?: string;
|
||||
};
|
||||
|
||||
export type CreatePlaylistResponse = undefined | { id: string };
|
||||
|
||||
export type DeletePlaylistQuery = { id: string };
|
||||
|
||||
export type DeletePlaylistRequest = {
|
||||
query: DeletePlaylistQuery;
|
||||
serverId?: string;
|
||||
};
|
||||
|
||||
export type DeletePlaylistResponse = null | undefined;
|
||||
|
||||
export type Playlist = {
|
||||
@@ -104,8 +107,6 @@ export type Playlist = {
|
||||
songCount: null | number;
|
||||
sync?: boolean | null;
|
||||
};
|
||||
export type PlaylistListArgs = BaseEndpointArgs & { query: PlaylistListQuery };
|
||||
|
||||
export interface PlaylistListQuery extends BaseQuery<PlaylistListSort> {
|
||||
_custom?: {
|
||||
jellyfin?: Partial<z.infer<typeof jfType._parameters.playlistList>>;
|
||||
@@ -116,26 +117,22 @@ export interface PlaylistListQuery extends BaseQuery<PlaylistListSort> {
|
||||
startIndex: number;
|
||||
}
|
||||
|
||||
export type PlaylistListResponse = BasePaginatedResponse<Playlist[]> | null | undefined;
|
||||
export type PlaylistListRequest = { query: PlaylistListQuery };
|
||||
|
||||
export type RemoveFromPlaylistArgs = BaseEndpointArgs & {
|
||||
query: RemoveFromPlaylistQuery;
|
||||
serverId?: string;
|
||||
};
|
||||
export type PlaylistListResponse = BasePaginatedResponse<Playlist[]> | null | undefined;
|
||||
|
||||
export type RemoveFromPlaylistQuery = {
|
||||
id: string;
|
||||
songId: string[];
|
||||
};
|
||||
|
||||
export type RemoveFromPlaylistResponse = null | undefined;
|
||||
|
||||
export type UpdatePlaylistArgs = BaseEndpointArgs & {
|
||||
body: UpdatePlaylistBody;
|
||||
query: UpdatePlaylistQuery;
|
||||
export type RemoveFromPlaylistRequest = {
|
||||
query: RemoveFromPlaylistQuery;
|
||||
serverId?: string;
|
||||
};
|
||||
|
||||
export type RemoveFromPlaylistResponse = null | undefined;
|
||||
|
||||
export type UpdatePlaylistBody = {
|
||||
_custom?: {
|
||||
navidrome?: {
|
||||
@@ -155,6 +152,12 @@ export type UpdatePlaylistQuery = {
|
||||
id: string;
|
||||
};
|
||||
|
||||
export type UpdatePlaylistRequest = {
|
||||
body: UpdatePlaylistBody;
|
||||
query: UpdatePlaylistQuery;
|
||||
serverId?: string;
|
||||
};
|
||||
|
||||
export type UpdatePlaylistResponse = null | undefined;
|
||||
|
||||
type PlaylistListSortMap = {
|
||||
@@ -189,10 +192,6 @@ export const playlistListSortMap: PlaylistListSortMap = {
|
||||
updatedAt: undefined,
|
||||
},
|
||||
};
|
||||
export type MoveItemArgs = BaseEndpointArgs & {
|
||||
query: MoveItemQuery;
|
||||
};
|
||||
|
||||
export type MoveItemQuery = {
|
||||
endingIndex: number;
|
||||
playlistId: string;
|
||||
@@ -200,15 +199,18 @@ export type MoveItemQuery = {
|
||||
trackId: string;
|
||||
};
|
||||
|
||||
export type PlaylistDetailArgs = BaseEndpointArgs & { query: PlaylistDetailQuery };
|
||||
export type MoveItemRequest = {
|
||||
query: MoveItemQuery;
|
||||
};
|
||||
|
||||
export type PlaylistDetailQuery = {
|
||||
id: string;
|
||||
};
|
||||
|
||||
export type PlaylistDetailRequest = { query: PlaylistDetailQuery };
|
||||
|
||||
export type PlaylistDetailResponse = Playlist;
|
||||
|
||||
export type PlaylistSongListArgs = BaseEndpointArgs & { query: PlaylistSongListQuery };
|
||||
export type PlaylistSongListQuery = {
|
||||
id: string;
|
||||
limit?: number;
|
||||
@@ -217,4 +219,6 @@ export type PlaylistSongListQuery = {
|
||||
startIndex: number;
|
||||
};
|
||||
|
||||
export type PlaylistSongListRequest = { query: PlaylistSongListQuery };
|
||||
|
||||
export type PlaylistSongListResponse = BasePaginatedResponse<Song[]> | null | undefined;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Album } from '/@/shared/types/domain/album-domain-types';
|
||||
import { BaseEndpointArgs } from '/@/shared/types/domain/api-domain-types';
|
||||
import { AlbumArtist } from '/@/shared/types/domain/artist-domain-types';
|
||||
import { Song } from '/@/shared/types/domain/song-domain-types';
|
||||
|
||||
@@ -17,10 +16,6 @@ export type SearchAlbumsQuery = {
|
||||
query?: string;
|
||||
};
|
||||
|
||||
export type SearchArgs = BaseEndpointArgs & {
|
||||
query: SearchQuery;
|
||||
};
|
||||
|
||||
export type SearchQuery = {
|
||||
albumArtistLimit?: number;
|
||||
albumArtistStartIndex?: number;
|
||||
@@ -32,6 +27,8 @@ export type SearchQuery = {
|
||||
songStartIndex?: number;
|
||||
};
|
||||
|
||||
export type SearchRequest = { query: SearchQuery };
|
||||
|
||||
export type SearchResponse = {
|
||||
albumArtists: AlbumArtist[];
|
||||
albums: Album[];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import i18n from 'src/i18n/i18n';
|
||||
|
||||
import { BaseEndpointArgs, BasePaginatedResponse } from '/@/shared/types/domain/api-domain-types';
|
||||
import { BasePaginatedResponse } from '/@/shared/types/adapter/api-controller-types';
|
||||
|
||||
export enum ServerListSortOptions {
|
||||
CREATED_AT = 'createdAt',
|
||||
@@ -40,7 +40,7 @@ export type ServerInfo = {
|
||||
version: string;
|
||||
};
|
||||
|
||||
export type ServerInfoArgs = BaseEndpointArgs;
|
||||
export type ServerInfoRequest = null;
|
||||
|
||||
export type ServerListItem = {
|
||||
credential: string;
|
||||
@@ -61,10 +61,10 @@ export type ServerMusicFolder = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type ServerMusicFolderListArgs = BaseEndpointArgs;
|
||||
|
||||
export type ServerMusicFolderListQuery = null;
|
||||
|
||||
export type ServerMusicFolderListRequest = null;
|
||||
|
||||
export type ServerMusicFolderListResponse =
|
||||
| BasePaginatedResponse<ServerMusicFolder[]>
|
||||
| null
|
||||
|
||||
@@ -6,11 +6,7 @@ import { JFSongListSort } from '/@/shared/api/jellyfin.types';
|
||||
import { jfType } from '/@/shared/api/jellyfin/jellyfin-types';
|
||||
import { NDSongListSort } from '/@/shared/api/navidrome.types';
|
||||
import { ndType } from '/@/shared/api/navidrome/navidrome-types';
|
||||
import {
|
||||
BaseEndpointArgs,
|
||||
BasePaginatedResponse,
|
||||
BaseQuery,
|
||||
} from '/@/shared/types/domain/api-domain-types';
|
||||
import { BasePaginatedResponse, BaseQuery } from '/@/shared/types/adapter/api-controller-types';
|
||||
import { RelatedArtist } from '/@/shared/types/domain/artist-domain-types';
|
||||
import { Genre } from '/@/shared/types/domain/genre-domain-types';
|
||||
import { Played, QueueSong } from '/@/shared/types/domain/player-domain-types';
|
||||
@@ -58,6 +54,7 @@ export const SongListSortOptionsLabels = {
|
||||
[SongListSortOptions.RELEASE_DATE]: i18n.t('filter.releaseDate'),
|
||||
[SongListSortOptions.YEAR]: i18n.t('filter.year'),
|
||||
};
|
||||
|
||||
export enum SongListSort {
|
||||
ALBUM = 'album',
|
||||
ALBUM_ARTIST = 'albumArtist',
|
||||
@@ -78,6 +75,7 @@ export enum SongListSort {
|
||||
RELEASE_DATE = 'releaseDate',
|
||||
YEAR = 'year',
|
||||
}
|
||||
|
||||
export type Song = {
|
||||
album: null | string;
|
||||
albumArtists: RelatedArtist[];
|
||||
@@ -121,7 +119,6 @@ export type Song = {
|
||||
userFavorite: boolean;
|
||||
userRating: null | number;
|
||||
};
|
||||
export type SongListArgs = BaseEndpointArgs & { query: SongListQuery };
|
||||
|
||||
export interface SongListQuery extends BaseQuery<SongListSort> {
|
||||
_custom?: {
|
||||
@@ -143,6 +140,8 @@ export interface SongListQuery extends BaseQuery<SongListSort> {
|
||||
startIndex: number;
|
||||
}
|
||||
|
||||
export type SongListRequest = { query: SongListQuery };
|
||||
|
||||
export type SongListResponse = BasePaginatedResponse<Song[]> | null | undefined;
|
||||
type SongListSortMap = {
|
||||
jellyfin: Record<SongListSort, JFSongListSort | undefined>;
|
||||
@@ -212,15 +211,12 @@ export const songListSortMap: SongListSortMap = {
|
||||
year: undefined,
|
||||
},
|
||||
};
|
||||
|
||||
export type GainInfo = {
|
||||
album?: number;
|
||||
track?: number;
|
||||
};
|
||||
|
||||
export type RandomSongListArgs = BaseEndpointArgs & {
|
||||
query: RandomSongListQuery;
|
||||
};
|
||||
|
||||
export type RandomSongListQuery = {
|
||||
genre?: string;
|
||||
limit?: number;
|
||||
@@ -229,30 +225,35 @@ export type RandomSongListQuery = {
|
||||
musicFolderId?: string;
|
||||
played: Played;
|
||||
};
|
||||
export type RandomSongListResponse = SongListResponse;
|
||||
|
||||
export type SimilarSongsArgs = BaseEndpointArgs & {
|
||||
query: SimilarSongsQuery;
|
||||
};
|
||||
export type RandomSongListRequest = { query: RandomSongListQuery };
|
||||
|
||||
export type RandomSongListResponse = SongListResponse;
|
||||
|
||||
export type SimilarSongsQuery = {
|
||||
albumArtistIds: string[];
|
||||
count?: number;
|
||||
songId: string;
|
||||
};
|
||||
export type SongDetailArgs = BaseEndpointArgs & { query: SongDetailQuery };
|
||||
|
||||
export type SimilarSongsRequest = { query: SimilarSongsQuery };
|
||||
|
||||
export type SongDetailQuery = { id: string };
|
||||
export type SongDetailResponse = null | Song | undefined;
|
||||
|
||||
export type TopSongListArgs = BaseEndpointArgs & { query: TopSongListQuery };
|
||||
export type SongDetailRequest = { query: SongDetailQuery };
|
||||
|
||||
export type SongDetailResponse = null | Song | undefined;
|
||||
|
||||
export type TopSongListQuery = {
|
||||
artist: string;
|
||||
artistId: string;
|
||||
limit?: number;
|
||||
};
|
||||
|
||||
export type TopSongListRequest = { query: TopSongListQuery };
|
||||
|
||||
export type TopSongListResponse = BasePaginatedResponse<Song[]> | null | undefined;
|
||||
|
||||
export const sortSongList = (
|
||||
songs: QueueSong[],
|
||||
sortBy: SongListSort,
|
||||
@@ -299,7 +300,7 @@ export const sortSongList = (
|
||||
results = orderBy(
|
||||
results,
|
||||
[
|
||||
(v) => v.genres?.[0].name.toLowerCase(),
|
||||
(v) => v.genres?.[0]?.name.toLowerCase(),
|
||||
(v) => v.album?.toLowerCase(),
|
||||
'discNumber',
|
||||
'trackNumber',
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { BaseEndpointArgs } from '/@/shared/types/domain/api-domain-types';
|
||||
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||
|
||||
export type Tag = {
|
||||
@@ -6,15 +5,13 @@ export type Tag = {
|
||||
options: string[];
|
||||
};
|
||||
|
||||
export type TagArgs = BaseEndpointArgs & {
|
||||
query: TagQuery;
|
||||
};
|
||||
|
||||
export type TagQuery = {
|
||||
folder?: string;
|
||||
type: LibraryItem.ALBUM | LibraryItem.SONG;
|
||||
};
|
||||
|
||||
export type TagRequest = { query: TagQuery };
|
||||
|
||||
export type TagsResponse = {
|
||||
boolTags?: string[];
|
||||
enumTags?: Tag[];
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import i18n from '/@/i18n/i18n';
|
||||
import { NDUserListSort } from '/@/shared/api/navidrome.types';
|
||||
import {
|
||||
BaseEndpointArgs,
|
||||
BasePaginatedResponse,
|
||||
BaseQuery,
|
||||
} from '/@/shared/types/domain/api-domain-types';
|
||||
import { BasePaginatedResponse, BaseQuery } from '/@/shared/types/adapter/api-controller-types';
|
||||
import { AnyLibraryItems, LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||
|
||||
export enum UserListSortOptions {
|
||||
@@ -21,24 +17,23 @@ export const UserListSortOptionsLabels = {
|
||||
[UserListSortOptions.UPDATED_AT]: i18n.t('filter.updatedAt'),
|
||||
};
|
||||
|
||||
export type FavoriteArgs = BaseEndpointArgs & { query: FavoriteQuery; serverId?: string };
|
||||
|
||||
export type FavoriteQuery = {
|
||||
id: string[];
|
||||
type: LibraryItem;
|
||||
};
|
||||
|
||||
export type FavoriteResponse = null | undefined;
|
||||
export type FavoriteRequest = { query: FavoriteQuery; serverId?: string };
|
||||
|
||||
export type FavoriteResponse = null;
|
||||
|
||||
export type RatingQuery = {
|
||||
item: AnyLibraryItems;
|
||||
rating: number;
|
||||
};
|
||||
|
||||
export type RatingResponse = null | undefined;
|
||||
export type RatingResponse = null;
|
||||
|
||||
export type SetRatingArgs = BaseEndpointArgs & { query: RatingQuery; serverId?: string };
|
||||
|
||||
export type UserListArgs = BaseEndpointArgs & { query: UserListQuery };
|
||||
export type SetRatingRequest = { query: RatingQuery; serverId?: string };
|
||||
|
||||
export interface UserListQuery extends BaseQuery<UserListSort> {
|
||||
_custom?: {
|
||||
@@ -51,6 +46,8 @@ export interface UserListQuery extends BaseQuery<UserListSort> {
|
||||
startIndex: number;
|
||||
}
|
||||
|
||||
export type UserListRequest = { query: UserListQuery };
|
||||
|
||||
export type UserListResponse = BasePaginatedResponse<User[]> | null | undefined;
|
||||
|
||||
type UserListSortMap = {
|
||||
@@ -75,18 +72,11 @@ export enum UserListSort {
|
||||
NAME = 'name',
|
||||
}
|
||||
|
||||
export type DownloadArgs = BaseEndpointArgs & {
|
||||
query: DownloadQuery;
|
||||
};
|
||||
|
||||
export type DownloadQuery = {
|
||||
id: string;
|
||||
};
|
||||
|
||||
export type ScrobbleArgs = BaseEndpointArgs & {
|
||||
query: ScrobbleQuery;
|
||||
serverId?: string;
|
||||
};
|
||||
export type DownloadRequest = { query: DownloadQuery };
|
||||
|
||||
export type ScrobbleQuery = {
|
||||
event?: 'pause' | 'start' | 'timeupdate' | 'unpause';
|
||||
@@ -95,9 +85,9 @@ export type ScrobbleQuery = {
|
||||
submission: boolean;
|
||||
};
|
||||
|
||||
export type ScrobbleResponse = null | undefined;
|
||||
export type ScrobbleRequest = { query: ScrobbleQuery; serverId?: string };
|
||||
|
||||
export type ShareItemArgs = BaseEndpointArgs & { body: ShareItemBody; serverId?: string };
|
||||
export type ScrobbleResponse = null;
|
||||
|
||||
export type ShareItemBody = {
|
||||
description: string;
|
||||
@@ -107,7 +97,9 @@ export type ShareItemBody = {
|
||||
resourceType: string;
|
||||
};
|
||||
|
||||
export type ShareItemResponse = undefined | { id: string };
|
||||
export type ShareItemRequest = { body: ShareItemBody; serverId?: string };
|
||||
|
||||
export type ShareItemResponse = null | { id: string };
|
||||
|
||||
export type User = {
|
||||
createdAt: null | string;
|
||||
|
||||
Reference in New Issue
Block a user