Skip to content

Commit

Permalink
refactor: use casters for type helpers & improve types
Browse files Browse the repository at this point in the history
- Removed the `?` operator for interfaces. This will make types more strict.
- MusicBrain IDs will now return `undefined` if an album/track doesn't have one.
- `artist.getInfo` now returns a bio object as opposed to a simple description.
- `artist.getInfo` now returns a similar artists property.
- `artist.getSimilar` now returns a proper float for matches.
- `track.getInfo` now returns `undefined` for user play counts.
- `track.getInfo` now returns `undefined` for album properties if they're missing.
  • Loading branch information
SapphicMoe committed Feb 29, 2024
1 parent 22966f9 commit 7fb2c17
Show file tree
Hide file tree
Showing 23 changed files with 503 additions and 423 deletions.
66 changes: 21 additions & 45 deletions src/classes/album.class.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
import { convertImageSizes, createLastFmURL } from '@utils/convert.js';
import Base from '~/base.js';
import { toInt, toArray, convertSearch } from '~/utils/caster.js';

import type { AlbumGetInfoParams, AlbumGetTopTagsParams, AlbumSearchParams } from '@params/index.js';
import type { AlbumGetInfoResponse, AlbumGetTopTagsResponse, AlbumSearchResponse } from '@responses/index.js';
import type {
AlbumGetInfoType,
AlbumGetTopTagsType,
AlbumSearchType,
TagType,
TrackReturnType,
} from '@typings/index.js';
import type { AlbumGetInfoType, AlbumGetTopTagsType, AlbumSearchType } from '@typings/index.js';

export default class Album extends Base {
/**
Expand All @@ -30,44 +25,30 @@ export default class Album extends Base {
...params,
});

const createTagObject = (tag?: TagType) =>
({
name: tag?.name,
url: tag?.url,
}) satisfies AlbumGetInfoType['tags'];

const createTrackObject = (track?: TrackReturnType) =>
({
rank: Number(track?.['@attr'].rank),
name: track?.name,
duration: Number(track?.duration),
url: track?.url,
}) satisfies AlbumGetInfoType['tracks'];

let tags;
if (Array.isArray(tagMatches)) tags = tagMatches.map((tag) => createTagObject(tag));
else tags = createTagObject(tagMatches);

let tracks;
if (Array.isArray(trackMatches)) tracks = trackMatches.map((track) => createTrackObject(track));
else if (trackMatches) tracks = createTrackObject(trackMatches);

return {
name: album.name,
mbid: album.mbid,
mbid: album.mbid === '' ? undefined : album.mbid,
artist: {
name: album.artist,
url: createLastFmURL('artist', album.artist),
url: createLastFmURL({ type: 'artist', value: album.artist }),
},
stats: {
scrobbles: Number(album.playcount),
listeners: Number(album.listeners),
scrobbles: toInt(album.playcount),
listeners: toInt(album.listeners),
},
userStats: {
userPlayCount: album.userplaycount,
},
tags,
tracks,
tags: toArray(tagMatches).map((tag) => ({
name: tag.name,
url: tag.url,
})),
tracks: toArray(trackMatches).map((track) => ({
rank: toInt(track['@attr'].rank),
name: track.name,
duration: toInt(track.duration),
url: track.url,
})),
url: album.url,
image: convertImageSizes(album.image),
};
Expand All @@ -90,9 +71,9 @@ export default class Album extends Base {
name: attr.album,
artist: {
name: attr.artist,
url: createLastFmURL('artist', attr.artist),
url: createLastFmURL({ type: 'artist', value: attr.artist }),
},
tags: tagMatches.map((tag) => ({
tags: toArray(tagMatches).map((tag) => ({
count: tag.count,
name: tag.name,
url: tag.url,
Expand Down Expand Up @@ -120,18 +101,13 @@ export default class Album extends Base {
});

return {
search: {
query: results['opensearch:Query'].searchTerms,
page: Number(results['opensearch:Query'].startPage),
itemsPerPage: Number(results['opensearch:itemsPerPage']),
totalResults: Number(results['opensearch:totalResults']),
},
albums: albumMatches.map((album) => ({
search: convertSearch(results),
albums: toArray(albumMatches).map((album) => ({
name: album.name,
mbid: album.mbid === '' ? undefined : album.mbid,
artist: {
name: album.artist,
url: createLastFmURL('artist', album.artist),
url: createLastFmURL({ type: 'artist', value: album.artist }),
},
url: album.url,
image: convertImageSizes(album.image),
Expand Down
90 changes: 51 additions & 39 deletions src/classes/artist.class.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { convertImageSizes, createLastFmURL } from '@utils/convert.js';
import Base from '~/base.js';
import { convertSearch, sanitizeBio, toArray, toBool, toFloat, toInt } from '~/utils/caster.js';

import type {
ArtistGetInfoParams,
Expand Down Expand Up @@ -40,16 +41,30 @@ export default class Artist extends Base {

return {
name: artist.name,
mbid: artist.mbid,
description: artist.bio.summary,
onTour: Boolean(Number(artist.ontour)).valueOf(),
mbid: artist.mbid === '' ? undefined : artist.mbid,
onTour: toBool(artist.ontour),
stats: {
scrobbles: Number(artist.stats.playcount),
listeners: Number(artist.stats.listeners),
scrobbles: toInt(artist.stats.playcount),
listeners: toInt(artist.stats.listeners),
},
userStats: {
userPlayCount: Number(artist.stats.userplaycount),
userPlayCount: Number.isNaN(toInt(artist.stats.userplaycount)) ? undefined : toInt(artist.stats.userplaycount),
},
tags: toArray(artist.tags.tag).map((tag) => ({
name: tag.name,
url: tag.url,
})),
bio: {
summary: sanitizeBio(artist.bio.summary),
extended: sanitizeBio(artist.bio.content),
published: new Date(`${artist.bio.published} UTC`),
url: artist.bio.links.link.href,
},
similarArtists: toArray(artist.similar.artist).map((artist) => ({
name: artist.name,
image: convertImageSizes(artist.image),
url: artist.url,
})),
url: artist.url,
};
}
Expand All @@ -72,13 +87,13 @@ export default class Artist extends Base {
search: {
artist: {
name: attr.artist,
url: createLastFmURL('artist', attr.artist),
url: createLastFmURL({ type: 'artist', value: attr.artist }),
},
},
artists: artistMatches.map((artist) => ({
match: Number(artist.match),
artists: toArray(artistMatches).map((artist) => ({
match: toFloat(artist.match),
name: artist.name,
mbid: artist.mbid,
mbid: artist.mbid === '' ? undefined : artist.mbid,
url: artist.url,
})),
};
Expand All @@ -104,16 +119,16 @@ export default class Artist extends Base {
search: {
artist: {
name: attr.artist,
url: createLastFmURL('artist', attr.artist),
url: createLastFmURL({ type: 'artist', value: attr.artist }),
},
page: Number(attr.page),
itemsPerPage: Number(attr.perPage),
totalPages: Number(attr.totalPages),
totalResults: Number(attr.total),
page: toInt(attr.page),
itemsPerPage: toInt(attr.perPage),
totalPages: toInt(attr.totalPages),
totalResults: toInt(attr.total),
},
albums: albumMatches.map((album) => ({
albums: toArray(albumMatches).map((album) => ({
name: album.name,
scrobbles: Number(album.playcount),
scrobbles: toInt(album.playcount),
artist: {
name: album.artist.name,
url: album.artist.url,
Expand All @@ -137,11 +152,13 @@ export default class Artist extends Base {
});

return {
artist: {
name: attr.artist,
url: createLastFmURL('artist', attr.artist),
search: {
artist: {
name: attr.artist,
url: createLastFmURL({ type: 'artist', value: attr.artist }),
},
},
tags: tagMatches.map((tag) => ({
tags: toArray(tagMatches).map((tag) => ({
count: tag.count,
name: tag.name,
url: tag.url,
Expand Down Expand Up @@ -169,24 +186,24 @@ export default class Artist extends Base {
search: {
artist: {
name: attr.artist,
url: createLastFmURL('artist', attr.artist),
url: createLastFmURL({ type: 'artist', value: attr.artist }),
},
page: Number(attr.page),
itemsPerPage: Number(attr.perPage),
totalPages: Number(attr.totalPages),
totalResults: Number(attr.total),
page: toInt(attr.page),
itemsPerPage: toInt(attr.perPage),
totalPages: toInt(attr.totalPages),
totalResults: toInt(attr.total),
},
tracks: trackMatches.map((track) => ({
rank: Number(track['@attr'].rank),
rank: toInt(track['@attr'].rank),
name: track.name,
mbid: track.mbid,
mbid: track.mbid === '' ? undefined : track.mbid,
artist: {
name: track.artist.name,
url: track.artist.url,
},
stats: {
scrobbles: Number(track.playcount),
listeners: Number(track.listeners),
scrobbles: toInt(track.playcount),
listeners: toInt(track.listeners),
},
url: track.url,
})),
Expand All @@ -213,16 +230,11 @@ export default class Artist extends Base {
});

return {
search: {
query: results['opensearch:Query'].searchTerms,
page: Number(results['opensearch:Query'].startPage),
itemsPerPage: Number(results['opensearch:itemsPerPage']),
totalResults: Number(results['opensearch:totalResults']),
},
artists: artistMatches.map((artist) => ({
search: convertSearch(results),
artists: toArray(artistMatches).map((artist) => ({
name: artist.name,
mbid: artist.mbid,
listeners: Number(artist.listeners),
mbid: artist.mbid === '' ? undefined : artist.mbid,
listeners: toInt(artist.listeners),
url: artist.url,
})),
};
Expand Down
55 changes: 28 additions & 27 deletions src/classes/chart.class.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Base from '~/base.js';
import { toArray, toInt } from '~/utils/caster.js';

import type { ChartGetTopArtistParams, ChartGetTopTagsParams, ChartGetTopTracksParams } from '@params/chart.params.js';
import type {
Expand All @@ -25,17 +26,17 @@ export default class Chart extends Base {

return {
search: {
page: Number(attr.page),
itemsPerPage: Number(attr.perPage),
totalPages: Number(attr.totalPages),
totalResults: Number(attr.total),
page: toInt(attr.page),
itemsPerPage: toInt(attr.perPage),
totalPages: toInt(attr.totalPages),
totalResults: toInt(attr.total),
},
artists: artistMatches.map((artist) => ({
artists: toArray(artistMatches).map((artist) => ({
name: artist.name,
mbid: artist.mbid,
mbid: artist.mbid === '' ? undefined : artist.mbid,
stats: {
scrobbles: Number(artist.playcount),
listeners: Number(artist.listeners),
scrobbles: toInt(artist.playcount),
listeners: toInt(artist.listeners),
},
url: artist.url,
})),
Expand All @@ -58,16 +59,16 @@ export default class Chart extends Base {

return {
search: {
page: Number(attr.page),
itemsPerPage: Number(attr.perPage),
totalPages: Number(attr.totalPages),
totalResults: Number(attr.total),
page: toInt(attr.page),
itemsPerPage: toInt(attr.perPage),
totalPages: toInt(attr.totalPages),
totalResults: toInt(attr.total),
},
tags: tagMatches.map((tag) => ({
tags: toArray(tagMatches).map((tag) => ({
name: tag.name,
stats: {
count: Number(tag.taggings),
reach: Number(tag.reach),
count: toInt(tag.taggings),
reach: toInt(tag.reach),
},
url: tag.url,
})),
Expand All @@ -90,23 +91,23 @@ export default class Chart extends Base {

return {
search: {
page: Number(attr.page),
itemsPerPage: Number(attr.perPage),
totalPages: Number(attr.totalPages),
totalResults: Number(attr.total),
page: toInt(attr.page),
itemsPerPage: toInt(attr.perPage),
totalPages: toInt(attr.totalPages),
totalResults: toInt(attr.total),
},
tracks: trackMatches.map((tag) => ({
name: tag.name,
mbid: tag.mbid,
tracks: toArray(trackMatches).map((track) => ({
name: track.name,
mbid: track.mbid === '' ? undefined : track.mbid,
stats: {
scrobbles: Number(tag.playcount),
listeners: Number(tag.listeners),
scrobbles: toInt(track.playcount),
listeners: toInt(track.listeners),
},
artist: {
name: tag.artist.name,
url: tag.artist.url,
name: track.artist.name,
url: track.artist.url,
},
url: tag.url,
url: track.url,
})),
};
}
Expand Down
Loading

0 comments on commit 7fb2c17

Please sign in to comment.