2023-06-10 16:52:27 +02:00
|
|
|
import { URL } from 'url';
|
|
|
|
import { ImageFormat } from '../types/Image';
|
|
|
|
import { URLS } from '../utils/Constants';
|
|
|
|
import SearchResultsParser from './SearchResultsParser';
|
|
|
|
import { SearchResultAlbum, SearchResultAny, SearchResultArtist, SearchResultFan, SearchResultLabel, SearchResultTrack, SearchResults } from '../types/Search';
|
|
|
|
import Limiter from '../utils/Limiter';
|
2023-10-28 14:55:26 +02:00
|
|
|
import BaseAPIWithImageSupport, { BaseAPIWithImageSupportParams } from '../common/BaseAPIWithImageSupport';
|
2023-06-10 16:52:27 +02:00
|
|
|
|
|
|
|
export enum SearchItemType {
|
|
|
|
All = 'All',
|
|
|
|
ArtistsAndLabels = 'ArtistsAndLabels',
|
|
|
|
Albums = 'Albums',
|
|
|
|
Tracks = 'Tracks',
|
|
|
|
Fans = 'Fans'
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface SearchAPISearchParams {
|
|
|
|
query: string;
|
|
|
|
page?: number;
|
|
|
|
albumImageFormat?: string | number | ImageFormat;
|
|
|
|
artistImageFormat?: string | number | ImageFormat;
|
|
|
|
}
|
|
|
|
|
2023-10-28 14:55:26 +02:00
|
|
|
export default class SearchAPI extends BaseAPIWithImageSupport {
|
2023-06-10 16:52:27 +02:00
|
|
|
|
2023-10-28 14:55:26 +02:00
|
|
|
async all(params: SearchAPISearchParams) {
|
2023-06-13 22:08:08 +02:00
|
|
|
return this.search({ ...params, itemType: SearchItemType.All });
|
2023-06-10 16:52:27 +02:00
|
|
|
}
|
|
|
|
|
2023-10-28 14:55:26 +02:00
|
|
|
async artistsAndLabels(params: SearchAPISearchParams) {
|
2023-06-13 22:08:08 +02:00
|
|
|
return this.search({ ...params, itemType: SearchItemType.ArtistsAndLabels });
|
2023-06-10 16:52:27 +02:00
|
|
|
}
|
|
|
|
|
2023-10-28 14:55:26 +02:00
|
|
|
async albums(params: SearchAPISearchParams) {
|
2023-06-13 22:08:08 +02:00
|
|
|
return this.search({ ...params, itemType: SearchItemType.Albums });
|
2023-06-10 16:52:27 +02:00
|
|
|
}
|
|
|
|
|
2023-10-28 14:55:26 +02:00
|
|
|
async tracks(params: SearchAPISearchParams) {
|
2023-06-13 22:08:08 +02:00
|
|
|
return this.search({ ...params, itemType: SearchItemType.Tracks });
|
2023-06-10 16:52:27 +02:00
|
|
|
}
|
|
|
|
|
2023-10-28 14:55:26 +02:00
|
|
|
async fans(params: SearchAPISearchParams) {
|
2023-06-13 22:08:08 +02:00
|
|
|
return this.search({ ...params, itemType: SearchItemType.Fans });
|
2023-06-10 16:52:27 +02:00
|
|
|
}
|
|
|
|
|
2023-06-13 22:08:08 +02:00
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
*/
|
2023-10-28 14:55:26 +02:00
|
|
|
protected async search(params: SearchAPISearchParams & { itemType: SearchItemType.ArtistsAndLabels }): Promise<SearchResults<SearchResultArtist | SearchResultLabel>>;
|
|
|
|
protected async search(params: SearchAPISearchParams & { itemType: SearchItemType.Albums }): Promise<SearchResults<SearchResultAlbum>>;
|
|
|
|
protected async search(params: SearchAPISearchParams & { itemType: SearchItemType.Tracks }): Promise<SearchResults<SearchResultTrack>>;
|
|
|
|
protected async search(params: SearchAPISearchParams & { itemType: SearchItemType.Fans }): Promise<SearchResults<SearchResultFan>>;
|
|
|
|
protected async search(params: SearchAPISearchParams & { itemType: SearchItemType.All }): Promise<SearchResults<SearchResultAny>>;
|
|
|
|
protected async search(params: SearchAPISearchParams & { itemType: SearchItemType }): Promise<any> {
|
2023-06-10 16:52:27 +02:00
|
|
|
const opts = {
|
|
|
|
itemType: params.itemType || SearchItemType.All,
|
2023-10-28 14:55:26 +02:00
|
|
|
albumImageFormat: await this.imageAPI.getFormat(params.albumImageFormat, 9),
|
|
|
|
artistImageFormat: await this.imageAPI.getFormat(params.artistImageFormat, 21)
|
2023-06-10 16:52:27 +02:00
|
|
|
};
|
2023-10-28 14:55:26 +02:00
|
|
|
const html = await this.fetch(SearchAPI.getSearchUrl(params));
|
2023-06-10 16:52:27 +02:00
|
|
|
return SearchResultsParser.parseResults(html, opts);
|
|
|
|
}
|
|
|
|
|
2023-06-13 22:08:08 +02:00
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
protected static getSearchUrl(params: SearchAPISearchParams & { itemType: SearchItemType }) {
|
2023-06-10 16:52:27 +02:00
|
|
|
const urlObj = new URL(URLS.SEARCH);
|
|
|
|
urlObj.searchParams.set('q', params.query);
|
|
|
|
urlObj.searchParams.set('page', (params.page || 1).toString());
|
|
|
|
switch (params.itemType) {
|
|
|
|
case SearchItemType.ArtistsAndLabels:
|
|
|
|
urlObj.searchParams.set('item_type', 'b');
|
|
|
|
break;
|
|
|
|
case SearchItemType.Albums:
|
|
|
|
urlObj.searchParams.set('item_type', 'a');
|
|
|
|
break;
|
|
|
|
case SearchItemType.Tracks:
|
|
|
|
urlObj.searchParams.set('item_type', 't');
|
|
|
|
break;
|
|
|
|
case SearchItemType.Fans:
|
|
|
|
urlObj.searchParams.set('item_type', 'f');
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
return urlObj.toString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class LimiterSearchAPI extends SearchAPI {
|
|
|
|
|
2023-10-28 14:55:26 +02:00
|
|
|
#limiter: Limiter;
|
|
|
|
|
|
|
|
constructor(params: BaseAPIWithImageSupportParams & { limiter: Limiter }) {
|
|
|
|
super(params);
|
|
|
|
this.#limiter = params.limiter;
|
|
|
|
}
|
|
|
|
|
|
|
|
async all(params: SearchAPISearchParams): Promise<SearchResults<SearchResultAny>> {
|
|
|
|
return this.#limiter.schedule(() => super.all(params));
|
2023-06-10 16:52:27 +02:00
|
|
|
}
|
|
|
|
|
2023-10-28 14:55:26 +02:00
|
|
|
async artistsAndLabels(params: SearchAPISearchParams): Promise<SearchResults<SearchResultArtist | SearchResultLabel>> {
|
|
|
|
return this.#limiter.schedule(() => super.artistsAndLabels(params));
|
2023-06-10 16:52:27 +02:00
|
|
|
}
|
|
|
|
|
2023-10-28 14:55:26 +02:00
|
|
|
async albums(params: SearchAPISearchParams): Promise<SearchResults<SearchResultAlbum>> {
|
|
|
|
return this.#limiter.schedule(() => super.albums(params));
|
2023-06-10 16:52:27 +02:00
|
|
|
}
|
|
|
|
|
2023-10-28 14:55:26 +02:00
|
|
|
async tracks(params: SearchAPISearchParams): Promise<SearchResults<SearchResultTrack>> {
|
|
|
|
return this.#limiter.schedule(() => super.tracks(params));
|
2023-06-10 16:52:27 +02:00
|
|
|
}
|
|
|
|
|
2023-10-28 14:55:26 +02:00
|
|
|
async fans(params: SearchAPISearchParams): Promise<SearchResults<SearchResultFan>> {
|
|
|
|
return this.#limiter.schedule(() => super.fans(params));
|
2023-06-10 16:52:27 +02:00
|
|
|
}
|
|
|
|
}
|