Query albums by genre

This commit is contained in:
simojenki
2021-03-06 20:06:08 +11:00
parent 5f9c240cdf
commit 1e5d020a75
7 changed files with 639 additions and 208 deletions

View File

@@ -1,7 +1,6 @@
import { option as O } from "fp-ts";
import { pipe } from "fp-ts/lib/function";
import {
MusicService,
Credentials,
@@ -13,33 +12,20 @@ import {
AlbumQuery,
slice2,
asResult,
ArtistSummary,
artistToArtistSummary,
albumToAlbumSummary,
Album,
AlbumSummary
} from "../src/music_service";
export const artistToArtistSummary = (
it: Artist
): ArtistSummary => ({
id: it.id,
name: it.name,
image: it.image,
});
export const albumToAlbumSummary = (
it: Album
): AlbumSummary => ({
id: it.id,
name: it.name,
year: it.year,
genre: it.genre,
});
type P<T> = (t: T) => boolean;
const all: P<any> = (_: any) => true;
const artistWithId = (id: string): P<Artist> => (artist: Artist) =>
const albumByArtist = (id: string): P<[Artist, Album]> => ([artist, _]) =>
artist.id === id;
const albumWithGenre = (genre: string): P<[Artist, Album]> => ([_, album]) =>
album.genre === genre;
export class InMemoryMusicService implements MusicService {
users: Record<string, string> = {};
artists: Artist[] = [];
@@ -76,24 +62,40 @@ export class InMemoryMusicService implements MusicService {
pipe(
this.artists.find((it) => it.id === id),
O.fromNullable,
O.map(it => Promise.resolve(it)),
O.map((it) => Promise.resolve(it)),
O.getOrElse(() => Promise.reject(`No artist with id '${id}'`))
),
albums: (q: AlbumQuery) =>
Promise.resolve(
this.artists.filter(
pipe(
O.fromNullable(q.artistId),
O.map(artistWithId),
O.getOrElse(() => all)
this.artists
.flatMap((artist) => artist.albums.map((album) => [artist, album]))
.filter(
pipe(
pipe(
O.fromNullable(q.artistId),
O.map(albumByArtist)
),
O.alt(() =>
pipe(
O.fromNullable(q.genre),
O.map(albumWithGenre)
)
),
O.getOrElse(() => all)
)
)
)
)
.then((artists) => artists.flatMap((it) => it.albums))
.then(it => it.map(albumToAlbumSummary))
.then((matches) => matches.map(([_, album]) => album as Album))
.then((it) => it.map(albumToAlbumSummary))
.then(slice2(q))
.then(asResult),
// album: (id: albumId) => Promise.resolve(this.artists.flatMap(it => it.albums).find(it => it.id === id))
album: (id: string) =>
pipe(
this.artists.flatMap((it) => it.albums).find((it) => it.id === id),
O.fromNullable,
O.map((it) => Promise.resolve(it)),
O.getOrElse(() => Promise.reject(`No album with id '${id}'`))
),
});
}