New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

musicbrainz-api

Package Overview
Dependencies
Maintainers
1
Versions
37
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

musicbrainz-api - npm Package Compare versions

Comparing version 0.11.0 to 0.12.0

lib/coverartarchive-api.d.ts

5

lib/musicbrainz-api.d.ts

@@ -149,2 +149,7 @@ export { XmlMetadata } from './xml/xml-metadata';

/**
* Lookup series
* @param seriesId Series MBID
*/
lookupSeries(seriesId: string): Promise<mb.ISeries>;
/**
* Lookup work

@@ -151,0 +156,0 @@ * @param workId Work MBID

54

lib/musicbrainz-api.js

@@ -38,3 +38,2 @@ "use strict";

const util_1 = require("util");
const retries = 3;
const debug = Debug('musicbrainz-api');

@@ -105,31 +104,11 @@ class MusicBrainzApi {

};
this.rateLimiter = new rate_limiter_1.RateLimiter(60, 50);
this.rateLimiter = new rate_limiter_1.RateLimiter(15, 18);
}
async restGet(relUrl, query = {}, attempt = 1) {
query.fmt = 'json';
let response;
await this.rateLimiter.limit();
do {
response = await got_1.default.get('ws/2' + relUrl, Object.assign({ searchParams: query, responseType: 'json' }, this.options));
if (response.statusCode !== 503)
break;
debug('Rate limiter kicked in, slowing down...');
await rate_limiter_1.RateLimiter.sleep(500);
} while (true);
switch (response.statusCode) {
case http_status_codes_1.StatusCodes.OK:
return response.body;
case http_status_codes_1.StatusCodes.BAD_REQUEST:
case http_status_codes_1.StatusCodes.NOT_FOUND:
throw new Error(`Got response status ${response.statusCode}: ${(0, http_status_codes_1.getReasonPhrase)(response.status)}`);
case http_status_codes_1.StatusCodes.SERVICE_UNAVAILABLE: // 503
default:
const msg = `Got response status ${response.statusCode} on attempt #${attempt} (${(0, http_status_codes_1.getReasonPhrase)(response.status)})`;
debug(msg);
if (attempt < retries) {
return this.restGet(relUrl, query, attempt + 1);
}
else
throw new Error(msg);
}
const response = await got_1.default.get('ws/2' + relUrl, Object.assign(Object.assign({}, this.options), { searchParams: query, responseType: 'json', retry: {
limit: 10
} }));
return response.body;
}

@@ -222,2 +201,9 @@ // -----------------------------------------------------------------------------------------------------------------

/**
* Lookup series
* @param seriesId Series MBID
*/
lookupSeries(seriesId) {
return this.lookupEntity('series', seriesId);
}
/**
* Lookup work

@@ -366,6 +352,6 @@ * @param workId Work MBID

await this.rateLimiter.limit();
const response = await got_1.default.post(path, Object.assign({ searchParams: { client: clientId }, headers: {
const response = await got_1.default.post(path, Object.assign(Object.assign({}, this.options), { searchParams: { client: clientId }, headers: {
authorization: digest,
'Content-Type': 'application/xml'
}, body: postData, throwHttpErrors: false }, this.options));
}, body: postData, throwHttpErrors: false }));
if (response.statusCode === http_status_codes_1.StatusCodes.UNAUTHORIZED) {

@@ -402,5 +388,5 @@ // Respond to digest challenge

};
const response = await got_1.default.post('login', Object.assign({ followRedirect: false, searchParams: {
const response = await got_1.default.post('login', Object.assign(Object.assign({}, this.options), { followRedirect: false, searchParams: {
returnto: redirectUri
}, form: formData }, this.options));
}, form: formData }));
const success = response.statusCode === http_status_codes_1.StatusCodes.MOVED_TEMPORARILY && response.headers.location === redirectUri;

@@ -417,5 +403,5 @@ if (success) {

const redirectUri = '/success';
const response = await got_1.default.get('logout', Object.assign({ followRedirect: false, searchParams: {
const response = await got_1.default.get('logout', Object.assign(Object.assign({}, this.options), { followRedirect: false, searchParams: {
returnto: redirectUri
} }, this.options));
} }));
const success = response.statusCode === http_status_codes_1.StatusCodes.MOVED_TEMPORARILY && response.headers.location === redirectUri;

@@ -441,3 +427,3 @@ if (success && this.session) {

formData.remember_me = 1;
const response = await got_1.default.post(`${entity}/${mbid}/edit`, Object.assign({ form: formData, followRedirect: false }, this.options));
const response = await got_1.default.post(`${entity}/${mbid}/edit`, Object.assign(Object.assign({}, this.options), { form: formData, followRedirect: false }));
if (response.statusCode === http_status_codes_1.StatusCodes.OK)

@@ -541,3 +527,3 @@ throw new Error(`Failed to submit form data`);

async getSession() {
const response = await got_1.default.get('login', Object.assign({ followRedirect: false, responseType: 'text' }, this.options));
const response = await got_1.default.get('login', Object.assign(Object.assign({}, this.options), { followRedirect: false, responseType: 'text' }));
return {

@@ -544,0 +530,0 @@ csrf: MusicBrainzApi.fetchCsrf(response.body)

@@ -223,2 +223,8 @@ import DateTimeFormat = Intl.DateTimeFormat;

}
export interface ISeries extends IEntity {
name: string;
type: string;
disambiguation: string;
'type-id': string;
}
export interface IUrl extends IEntity {

@@ -225,0 +231,0 @@ id: string;

@@ -6,4 +6,4 @@ export declare class RateLimiter {

private readonly period;
constructor(period: number, maxCalls: number);
constructor(maxCalls: number, period: number);
limit(): Promise<void>;
}

@@ -10,5 +10,6 @@ "use strict";

}
constructor(period, maxCalls) {
constructor(maxCalls, period) {
this.maxCalls = maxCalls;
this.queue = [];
debug(`Rate limiter initialized with max ${maxCalls} calls in ${period} seconds.`);
this.period = 1000 * period;

@@ -22,2 +23,3 @@ }

}
// debug(`Current rate is ${this.queue.length} per ${this.period / 1000} sec`);
if (this.queue.length >= this.maxCalls) {

@@ -24,0 +26,0 @@ const delay = this.queue[0] + this.period - now;

{
"name": "musicbrainz-api",
"version": "0.11.0",
"version": "0.12.0",
"description": "MusicBrainz API client for reading and submitting metadata",
"main": "lib/musicbrainz-api",
"types": "lib/musicbrainz-api",
"main": "lib/index",
"types": "lib/index",
"author": {

@@ -23,3 +23,9 @@ "name": "Borewit",

"submit",
"metabrainz"
"metabrainz",
"Cover Art Archive",
"coverartarchive",
"coverartarchive.org",
"album art",
"covers",
"download covers"
],

@@ -26,0 +32,0 @@ "license": "MIT",

@@ -118,2 +118,16 @@ [![Node.js CI](https://github.com/Borewit/musicbrainz-api/actions/workflows/nodejs-ci.yml/badge.svg)](https://github.com/Borewit/musicbrainz-api/actions/workflows/nodejs-ci.yml)

### Lookup collection
Lookup an instrument
```js
const collection = await mbApi.lookupCollection('de4fdfc4-53aa-458a-b463-8761cc7f5af8');
```
Lookup an event
```js
const event = await mbApi.lookupEvent('6d32c658-151e-45ec-88c4-fb8787524d61');
```
### Lookup instrument

@@ -141,2 +155,6 @@

```js
const place = await mbApi.lookupSeries('1ae6c9bc-2931-4d75-bee4-3dc53dfd246a');
```
The second argument can be used to pass [subqueries](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2#Subqueries), which will return more (nested) information:

@@ -480,2 +498,23 @@ ```js

## Cover Art Archive API
Implementation of the [Cover Art Archive API](https://musicbrainz.org/doc/Cover_Art_Archive/API).
```js
import {CoverArtArchiveApi} from 'musicbrainz-api';
coverArtArchiveApiClient.getReleaseCovers(releaseMbid).then(releaseCoverInfo => {
console.log('Release cover info', releaseCoverInfo);
});
coverArtArchiveApiClient.getReleaseCovers(releaseMbid, 'front').then(releaseCoverInfo => {
console.log('Get best front cover', releaseCoverInfo);
});
coverArtArchiveApiClient.getReleaseCovers(releaseMbid, 'back').then(releaseCoverInfo => {
console.log('Get best back cover', releaseCoverInfo);
});
```
## Compatibility

@@ -482,0 +521,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc