2021-04-16 04:34:29 +00:00
|
|
|
import ExtendableError from 'es6-error';
|
|
|
|
|
import Client from './client.js';
|
|
|
|
|
import { filterObjectValues } from '../util.js';
|
2016-12-20 05:21:07 +00:00
|
|
|
|
2021-04-16 04:34:29 +00:00
|
|
|
export class MusicBrainzError extends ExtendableError {
|
|
|
|
|
constructor(message, response) {
|
|
|
|
|
super(message);
|
|
|
|
|
this.response = response;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-12-20 05:21:07 +00:00
|
|
|
|
|
|
|
|
export default class MusicBrainz extends Client {
|
2018-08-04 19:04:19 +00:00
|
|
|
constructor({
|
|
|
|
|
baseURL = process.env.MUSICBRAINZ_BASE_URL ||
|
|
|
|
|
'http://musicbrainz.org/ws/2/',
|
|
|
|
|
// MusicBrainz API requests are limited to an *average* of 1 req/sec.
|
|
|
|
|
// That means if, for example, we only need to make a few API requests to
|
|
|
|
|
// fulfill a query, we might as well make them all at once - as long as
|
|
|
|
|
// we then wait a few seconds before making more. In practice this can
|
|
|
|
|
// seemingly be set to about 5 requests every 5 seconds before we're
|
|
|
|
|
// considered to exceed the rate limit.
|
|
|
|
|
limit = 5,
|
|
|
|
|
period = 5500,
|
|
|
|
|
...options
|
|
|
|
|
} = {}) {
|
2021-04-16 04:34:29 +00:00
|
|
|
super({ baseURL, limit, period, ...options });
|
2016-12-20 05:21:07 +00:00
|
|
|
}
|
|
|
|
|
|
2021-04-16 04:34:29 +00:00
|
|
|
parseErrorMessage(err) {
|
|
|
|
|
if (err.name === 'HTTPError') {
|
|
|
|
|
const { body } = err.response;
|
|
|
|
|
if (body && body.error) {
|
|
|
|
|
return new MusicBrainzError(`${body.error}`, err.response);
|
|
|
|
|
}
|
2016-12-20 05:21:07 +00:00
|
|
|
}
|
2021-04-16 04:34:29 +00:00
|
|
|
return super.parseErrorMessage(err);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get(url, options = {}) {
|
|
|
|
|
options = {
|
|
|
|
|
resolveBodyOnly: true,
|
|
|
|
|
...options,
|
|
|
|
|
searchParams: {
|
|
|
|
|
fmt: 'json',
|
|
|
|
|
...options.searchParams,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
return super.get(url, options);
|
2016-12-20 05:21:07 +00:00
|
|
|
}
|
|
|
|
|
|
2017-11-07 05:54:56 +00:00
|
|
|
stringifyParams(params) {
|
2016-12-20 05:21:07 +00:00
|
|
|
if (Array.isArray(params.inc)) {
|
|
|
|
|
params = {
|
|
|
|
|
...params,
|
2021-04-16 04:34:29 +00:00
|
|
|
inc: params.inc.join('+'),
|
|
|
|
|
};
|
2016-12-20 05:21:07 +00:00
|
|
|
}
|
|
|
|
|
if (Array.isArray(params.type)) {
|
|
|
|
|
params = {
|
|
|
|
|
...params,
|
2021-04-16 04:34:29 +00:00
|
|
|
type: params.type.join('|'),
|
|
|
|
|
};
|
2016-12-20 05:21:07 +00:00
|
|
|
}
|
|
|
|
|
if (Array.isArray(params.status)) {
|
|
|
|
|
params = {
|
|
|
|
|
...params,
|
2021-04-16 04:34:29 +00:00
|
|
|
status: params.status.join('|'),
|
|
|
|
|
};
|
2016-12-20 05:21:07 +00:00
|
|
|
}
|
2021-04-16 04:34:29 +00:00
|
|
|
return new URLSearchParams(
|
|
|
|
|
filterObjectValues(params, (value) => value != null && value !== '')
|
|
|
|
|
).toString();
|
2016-12-20 05:21:07 +00:00
|
|
|
}
|
|
|
|
|
|
2017-11-07 05:54:56 +00:00
|
|
|
getURL(path, params) {
|
2021-04-16 04:34:29 +00:00
|
|
|
const query = params ? this.stringifyParams(params) : '';
|
|
|
|
|
return query ? `${path}?${query}` : path;
|
2016-12-20 05:21:07 +00:00
|
|
|
}
|
|
|
|
|
|
2017-11-07 05:54:56 +00:00
|
|
|
getLookupURL(entity, id, params) {
|
2016-12-20 05:21:07 +00:00
|
|
|
if (id == null) {
|
2021-04-16 04:34:29 +00:00
|
|
|
return this.getBrowseURL(entity, params);
|
2016-12-20 05:21:07 +00:00
|
|
|
}
|
2021-04-16 04:34:29 +00:00
|
|
|
return this.getURL(`${entity}/${id}`, params);
|
2016-12-20 05:21:07 +00:00
|
|
|
}
|
|
|
|
|
|
2017-11-07 05:54:56 +00:00
|
|
|
lookup(entity, id, params = {}) {
|
2021-04-16 04:34:29 +00:00
|
|
|
const url = this.getLookupURL(entity, id, params);
|
|
|
|
|
return this.get(url);
|
2016-12-20 05:21:07 +00:00
|
|
|
}
|
|
|
|
|
|
2017-11-07 05:54:56 +00:00
|
|
|
getBrowseURL(entity, params) {
|
2021-04-16 04:34:29 +00:00
|
|
|
return this.getURL(entity, params);
|
2016-12-20 05:21:07 +00:00
|
|
|
}
|
|
|
|
|
|
2017-11-07 05:54:56 +00:00
|
|
|
browse(entity, params = {}) {
|
2021-04-16 04:34:29 +00:00
|
|
|
const url = this.getBrowseURL(entity, params);
|
|
|
|
|
return this.get(url);
|
2016-12-20 05:21:07 +00:00
|
|
|
}
|
|
|
|
|
|
2017-11-07 05:54:56 +00:00
|
|
|
getSearchURL(entity, query, params) {
|
2021-04-16 04:34:29 +00:00
|
|
|
return this.getURL(entity, { ...params, query });
|
2016-12-20 05:21:07 +00:00
|
|
|
}
|
|
|
|
|
|
2017-11-07 05:54:56 +00:00
|
|
|
search(entity, query, params = {}) {
|
2021-04-16 04:34:29 +00:00
|
|
|
const url = this.getSearchURL(entity, query, params);
|
|
|
|
|
return this.get(url);
|
2016-12-20 05:21:07 +00:00
|
|
|
}
|
|
|
|
|
}
|