bandcamp-fetch/src/lib/discovery/DiscoverResultParser.ts

66 lines
2.2 KiB
TypeScript
Raw Normal View History

2023-10-29 10:02:57 +01:00
import Album from '../types/Album.js';
import Artist from '../types/Artist.js';
import { DiscoverParams, DiscoverResult } from '../types/Discovery.js';
import { ImageFormat } from '../types/Image.js';
import { ParseError } from '../utils/Parse.js';
2023-06-10 16:52:27 +02:00
interface DiscoverResultParseOptions {
imageBaseUrl: string;
albumImageFormat: ImageFormat | null;
artistImageFormat: ImageFormat | null;
}
export default class DiscoverResultParser {
static parseDiscoverResult(json: any, opts: DiscoverResultParseOptions, resultParams: DiscoverParams): DiscoverResult {
if (typeof json === 'object' && Array.isArray(json.items)) {
const items = json.items.filter(
(item: any) => item.type === 'a').map((item: any) => {
const artist: Artist = {
type: 'artist',
name: item.secondary_text
};
const album: Album = {
type: 'album',
name: item.primary_text,
genre: item.genre_text,
artist,
location: item.location_text
};
if (item.url_hints) {
artist.url = `https://${item.url_hints.subdomain}.bandcamp.com`;
}
if (artist.url) {
album.url = `${artist.url}/album/${item.url_hints.slug}`;
}
if (item.art_id && opts.albumImageFormat) {
album.imageUrl = `${opts.imageBaseUrl}/img/a${item.art_id}_${opts.albumImageFormat.id}.jpg`;
}
if (item.featured_track) {
album.featuredTrack = {
name: item.featured_track.title,
duration: item.featured_track.duration,
streamUrl: item.featured_track.file?.['mp3-128']
2023-06-10 16:52:27 +02:00
};
const streamUrlHQ = item.featured_track.file?.['mp3-v0'];
if (streamUrlHQ) {
album.featuredTrack.streamUrlHQ = streamUrlHQ;
}
2023-06-10 16:52:27 +02:00
}
if (item.bio_image && opts.artistImageFormat) {
artist.imageUrl = `${opts.imageBaseUrl}/img/${item.bio_image.image_id}_${opts.artistImageFormat.id}.jpg`;
}
return album;
}) as Album[];
return {
items,
total: json.total_count,
params: resultParams
};
}
throw new ParseError('Failed to parse discover results: data is missing or has invalid \'items\' field.', json);
}
}