export type Credentials = { username: string; password: string }; export function isSuccess( authResult: AuthSuccess | AuthFailure ): authResult is AuthSuccess { return (authResult as AuthSuccess).authToken !== undefined; } export function isFailure( authResult: any | AuthFailure ): authResult is AuthFailure { return (authResult as AuthFailure).message !== undefined; } export type AuthSuccess = { authToken: string; userId: string; nickname: string; }; export type AuthFailure = { message: string; }; export type ArtistSummary = { id: string; name: string; image: Images } export type Images = { small: string | undefined, medium: string | undefined, large: string | undefined, } export type Artist = ArtistSummary & { albums: Album[] }; export type Album = { id: string; name: string; year: string | undefined; genre: string | undefined; }; export type Paging = { _index: number; _count: number; }; export type Result = { results: T[]; total: number; }; export function slice2({ _index, _count }: Paging) { return (things: T[]): [T[], number] => [ things.slice(_index, _index + _count), things.length, ]; } export const asResult = ([results, total]: [T[], number]) => ({ results, total, }); export type ArtistQuery = Paging export type AlbumQuery = Paging & { artistId?: string } export interface MusicService { generateToken(credentials: Credentials): Promise; login(authToken: string): Promise; } export interface MusicLibrary { artists(q: ArtistQuery): Promise>; artist(id: string): Promise; albums(q: AlbumQuery): Promise>; }