musicbrainz-api 0.10.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.idea/jpa-buddy.xml +6 -0
- package/README.md +11 -16
- package/lib/digest-auth.js +6 -6
- package/lib/musicbrainz-api.d.ts +17 -17
- package/lib/musicbrainz-api.js +17 -17
- package/lib/musicbrainz.types.d.ts +6 -6
- package/lib/rate-limiter.js +3 -3
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -94,13 +94,13 @@ Arguments:
|
|
|
94
94
|
* MBID [(MusicBrainz identifier)](https://wiki.musicbrainz.org/MusicBrainz_Identifier)
|
|
95
95
|
|
|
96
96
|
```js
|
|
97
|
-
const artist = await mbApi.lookupEntity('artist',
|
|
97
|
+
const artist = await mbApi.lookupEntity('artist', 'ab2528d9-719f-4261-8098-21849222a0f2');
|
|
98
98
|
```
|
|
99
99
|
|
|
100
100
|
### Lookup area
|
|
101
101
|
|
|
102
102
|
```js
|
|
103
|
-
const area = await mbApi.lookupArea(
|
|
103
|
+
const area = await mbApi.lookupArea('ab2528d9-719f-4261-8098-21849222a0f2');
|
|
104
104
|
```
|
|
105
105
|
|
|
106
106
|
### Lookup artist
|
|
@@ -108,7 +108,7 @@ const area = await mbApi.lookupArea({query: 'ab2528d9-719f-4261-8098-21849222a0f
|
|
|
108
108
|
Lookup an `artist` and include their `releases`, `release-groups` and `aliases`
|
|
109
109
|
|
|
110
110
|
```js
|
|
111
|
-
const artist = await mbApi.lookupArtist(
|
|
111
|
+
const artist = await mbApi.lookupArtist('ab2528d9-719f-4261-8098-21849222a0f2');
|
|
112
112
|
```
|
|
113
113
|
|
|
114
114
|
### Lookup instrument
|
|
@@ -116,7 +116,7 @@ const artist = await mbApi.lookupArtist({query: 'ab2528d9-719f-4261-8098-2184922
|
|
|
116
116
|
Lookup an instrument
|
|
117
117
|
|
|
118
118
|
```js
|
|
119
|
-
const
|
|
119
|
+
const instrument = await mbApi.lookupInstrument('b3eac5f9-7859-4416-ac39-7154e2e8d348');
|
|
120
120
|
```
|
|
121
121
|
|
|
122
122
|
### Lookup label
|
|
@@ -124,13 +124,13 @@ const artist = await mbApi.lookupInstrument({query: 'b3eac5f9-7859-4416-ac39-715
|
|
|
124
124
|
Lookup a label
|
|
125
125
|
|
|
126
126
|
```js
|
|
127
|
-
const
|
|
127
|
+
const label = await mbApi.lookupLabel('25dda9f9-f069-4898-82f0-59330a106c7f');
|
|
128
128
|
```
|
|
129
129
|
|
|
130
130
|
### Lookup place
|
|
131
131
|
|
|
132
132
|
```js
|
|
133
|
-
const
|
|
133
|
+
const place = await mbApi.lookupPlace('e6cfb74d-d69b-44c3-b890-1b3f509816e4');
|
|
134
134
|
```
|
|
135
135
|
|
|
136
136
|
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:
|
|
@@ -142,32 +142,27 @@ const artist = await mbApi.lookupArtist('ab2528d9-719f-4261-8098-21849222a0f2',
|
|
|
142
142
|
|
|
143
143
|
The second argument can be used to pass [subqueries](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2#Subqueries):
|
|
144
144
|
```js
|
|
145
|
-
const
|
|
145
|
+
const recording = await mbApi.lookupRecording('16afa384-174e-435e-bfa3-5591accda31c', ['artists', 'url-rels']);
|
|
146
146
|
```
|
|
147
147
|
|
|
148
148
|
### Lookup release
|
|
149
149
|
```js
|
|
150
|
-
const release = await mbApi.lookupRelease(
|
|
150
|
+
const release = await mbApi.lookupRelease('976e0677-a480-4a5e-a177-6a86c1900bbf', ['artists', 'url-rels']);
|
|
151
151
|
```
|
|
152
152
|
|
|
153
153
|
### Lookup release-group
|
|
154
154
|
```js
|
|
155
|
-
const releaseGroup = await mbApi.lookupReleaseGroup(
|
|
155
|
+
const releaseGroup = await mbApi.lookupReleaseGroup('19099ea5-3600-4154-b482-2ec68815883e');
|
|
156
156
|
```
|
|
157
157
|
|
|
158
158
|
### Lookup work
|
|
159
159
|
```js
|
|
160
|
-
const work = await mbApi.lookupWork(
|
|
160
|
+
const work = await mbApi.lookupWork('b2aa02f4-6c95-43be-a426-aedb9f9a3805');
|
|
161
161
|
```
|
|
162
162
|
|
|
163
163
|
### Lookup URL
|
|
164
164
|
```js
|
|
165
|
-
const url = await mbApi.lookupUrl(
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### Lookup URL
|
|
169
|
-
```js
|
|
170
|
-
const url = await mbApi.lookupUrl({query: 'c69556a6-7ded-4c54-809c-afb45a1abe7d'});
|
|
165
|
+
const url = await mbApi.lookupUrl('c69556a6-7ded-4c54-809c-afb45a1abe7d');
|
|
171
166
|
```
|
|
172
167
|
|
|
173
168
|
## Browse entities
|
package/lib/digest-auth.js
CHANGED
|
@@ -7,12 +7,6 @@ function md5(str) {
|
|
|
7
7
|
return crypto.createHash('md5').update(str).digest('hex'); // lgtm [js/insufficient-password-hash]
|
|
8
8
|
}
|
|
9
9
|
class DigestAuth {
|
|
10
|
-
constructor(credentials) {
|
|
11
|
-
this.credentials = credentials;
|
|
12
|
-
this.hasAuth = false;
|
|
13
|
-
this.sentAuth = false;
|
|
14
|
-
this.bearerToken = null;
|
|
15
|
-
}
|
|
16
10
|
/**
|
|
17
11
|
* RFC 2617: handle both MD5 and MD5-sess algorithms.
|
|
18
12
|
*
|
|
@@ -25,6 +19,12 @@ class DigestAuth {
|
|
|
25
19
|
const ha1 = md5(user + ':' + realm + ':' + pass); // lgtm [js/insufficient-password-hash]
|
|
26
20
|
return algorithm && algorithm.toLowerCase() === 'md5-sess' ? md5(ha1 + ':' + nonce + ':' + cnonce) : ha1;
|
|
27
21
|
}
|
|
22
|
+
constructor(credentials) {
|
|
23
|
+
this.credentials = credentials;
|
|
24
|
+
this.hasAuth = false;
|
|
25
|
+
this.sentAuth = false;
|
|
26
|
+
this.bearerToken = null;
|
|
27
|
+
}
|
|
28
28
|
digest(method, path, authHeader) {
|
|
29
29
|
// TODO: More complete implementation of RFC 2617.
|
|
30
30
|
// - support qop="auth-int" only
|
package/lib/musicbrainz-api.d.ts
CHANGED
|
@@ -5,8 +5,8 @@ export { XmlRecording } from './xml/xml-recording';
|
|
|
5
5
|
import { XmlMetadata } from './xml/xml-metadata';
|
|
6
6
|
import * as mb from './musicbrainz.types';
|
|
7
7
|
export * from './musicbrainz.types';
|
|
8
|
-
export
|
|
9
|
-
export
|
|
8
|
+
export type RelationsIncludes = 'area-rels' | 'artist-rels' | 'event-rels' | 'instrument-rels' | 'label-rels' | 'place-rels' | 'recording-rels' | 'release-rels' | 'release-group-rels' | 'series-rels' | 'url-rels' | 'work-rels';
|
|
9
|
+
export type SubQueryIncludes =
|
|
10
10
|
/**
|
|
11
11
|
* include discids for all media in the releases
|
|
12
12
|
*/
|
|
@@ -27,21 +27,21 @@ export declare type SubQueryIncludes =
|
|
|
27
27
|
* include only those releases where the artist appears on one of the tracks, only valid on artists in combination with `releases`
|
|
28
28
|
*/
|
|
29
29
|
| 'various-artists';
|
|
30
|
-
export
|
|
31
|
-
export
|
|
32
|
-
export
|
|
33
|
-
export
|
|
34
|
-
export
|
|
35
|
-
export
|
|
36
|
-
export
|
|
37
|
-
export
|
|
38
|
-
export
|
|
39
|
-
export
|
|
40
|
-
export
|
|
41
|
-
export
|
|
42
|
-
export
|
|
43
|
-
export
|
|
44
|
-
export
|
|
30
|
+
export type MiscIncludes = 'aliases' | 'annotation' | 'tags' | 'genres' | 'ratings' | 'media';
|
|
31
|
+
export type AreaIncludes = MiscIncludes | RelationsIncludes;
|
|
32
|
+
export type ArtistIncludes = MiscIncludes | RelationsIncludes | 'recordings' | 'releases' | 'release-groups' | 'works';
|
|
33
|
+
export type CollectionIncludes = MiscIncludes | RelationsIncludes | 'user-collections';
|
|
34
|
+
export type EventIncludes = MiscIncludes | RelationsIncludes;
|
|
35
|
+
export type GenreIncludes = MiscIncludes;
|
|
36
|
+
export type InstrumentIncludes = MiscIncludes | RelationsIncludes;
|
|
37
|
+
export type LabelIncludes = MiscIncludes | RelationsIncludes | 'releases';
|
|
38
|
+
export type PlaceIncludes = MiscIncludes | RelationsIncludes;
|
|
39
|
+
export type RecordingIncludes = MiscIncludes | RelationsIncludes | SubQueryIncludes | 'artists' | 'releases' | 'isrcs';
|
|
40
|
+
export type ReleasesIncludes = MiscIncludes | SubQueryIncludes | RelationsIncludes | 'artists' | 'collections' | 'labels' | 'recordings' | 'release-groups';
|
|
41
|
+
export type ReleaseGroupIncludes = MiscIncludes | SubQueryIncludes | RelationsIncludes | 'artists' | 'releases';
|
|
42
|
+
export type SeriesIncludes = MiscIncludes | RelationsIncludes;
|
|
43
|
+
export type WorkIncludes = MiscIncludes | RelationsIncludes;
|
|
44
|
+
export type UrlIncludes = RelationsIncludes;
|
|
45
45
|
export interface IFormData {
|
|
46
46
|
[key: string]: string | number;
|
|
47
47
|
}
|
package/lib/musicbrainz-api.js
CHANGED
|
@@ -37,23 +37,6 @@ const util_1 = require("util");
|
|
|
37
37
|
const retries = 3;
|
|
38
38
|
const debug = Debug('musicbrainz-api');
|
|
39
39
|
class MusicBrainzApi {
|
|
40
|
-
constructor(_config) {
|
|
41
|
-
this.config = {
|
|
42
|
-
baseUrl: 'https://musicbrainz.org'
|
|
43
|
-
};
|
|
44
|
-
Object.assign(this.config, _config);
|
|
45
|
-
const cookieJar = new tough.CookieJar();
|
|
46
|
-
this.getCookies = (0, util_1.promisify)(cookieJar.getCookies.bind(cookieJar));
|
|
47
|
-
this.options = {
|
|
48
|
-
prefixUrl: this.config.baseUrl,
|
|
49
|
-
timeout: 20 * 1000,
|
|
50
|
-
headers: {
|
|
51
|
-
'User-Agent': `${this.config.appName}/${this.config.appVersion} ( ${this.config.appContactInfo} )`
|
|
52
|
-
},
|
|
53
|
-
cookieJar
|
|
54
|
-
};
|
|
55
|
-
this.rateLimiter = new rate_limiter_1.RateLimiter(60, 50);
|
|
56
|
-
}
|
|
57
40
|
static escapeText(text) {
|
|
58
41
|
let str = '';
|
|
59
42
|
for (const chr of text) {
|
|
@@ -101,6 +84,23 @@ class MusicBrainzApi {
|
|
|
101
84
|
}
|
|
102
85
|
}
|
|
103
86
|
}
|
|
87
|
+
constructor(_config) {
|
|
88
|
+
this.config = {
|
|
89
|
+
baseUrl: 'https://musicbrainz.org'
|
|
90
|
+
};
|
|
91
|
+
Object.assign(this.config, _config);
|
|
92
|
+
const cookieJar = new tough.CookieJar();
|
|
93
|
+
this.getCookies = (0, util_1.promisify)(cookieJar.getCookies.bind(cookieJar));
|
|
94
|
+
this.options = {
|
|
95
|
+
prefixUrl: this.config.baseUrl,
|
|
96
|
+
timeout: 20 * 1000,
|
|
97
|
+
headers: {
|
|
98
|
+
'User-Agent': `${this.config.appName}/${this.config.appVersion} ( ${this.config.appContactInfo} )`
|
|
99
|
+
},
|
|
100
|
+
cookieJar
|
|
101
|
+
};
|
|
102
|
+
this.rateLimiter = new rate_limiter_1.RateLimiter(60, 50);
|
|
103
|
+
}
|
|
104
104
|
async restGet(relUrl, query = {}, attempt = 1) {
|
|
105
105
|
query.fmt = 'json';
|
|
106
106
|
let response;
|
|
@@ -81,7 +81,7 @@ export interface IInstrument extends IEntity {
|
|
|
81
81
|
type: string;
|
|
82
82
|
description: string;
|
|
83
83
|
}
|
|
84
|
-
export
|
|
84
|
+
export type ReleaseQuality = 'normal';
|
|
85
85
|
export interface IRelease extends IEntity {
|
|
86
86
|
title: string;
|
|
87
87
|
'text-representation': {
|
|
@@ -109,7 +109,7 @@ export interface IReleaseEvent {
|
|
|
109
109
|
area?: IArea;
|
|
110
110
|
date?: string;
|
|
111
111
|
}
|
|
112
|
-
export
|
|
112
|
+
export type MediaFormatType = 'Digital Media';
|
|
113
113
|
export interface IRecording extends IEntity {
|
|
114
114
|
video: boolean;
|
|
115
115
|
length: number;
|
|
@@ -185,7 +185,7 @@ export interface IReleaseGroupList extends ISearchResult {
|
|
|
185
185
|
export interface IUrlList extends ISearchResult {
|
|
186
186
|
urls: IUrlMatch[];
|
|
187
187
|
}
|
|
188
|
-
export
|
|
188
|
+
export type RelationDirection = 'backward' | 'forward';
|
|
189
189
|
export interface IRelation {
|
|
190
190
|
'attribute-ids': any;
|
|
191
191
|
direction: RelationDirection;
|
|
@@ -237,8 +237,8 @@ export interface IReleaseSearchResult extends ISearchResult {
|
|
|
237
237
|
/**
|
|
238
238
|
* https://musicbrainz.org/doc/Development/XML_Web_Service/Version_2#Subqueries
|
|
239
239
|
*/
|
|
240
|
-
export
|
|
241
|
-
export
|
|
240
|
+
export type EntityType = 'area' | 'artist' | 'collection' | 'event' | 'instrument' | 'label' | 'place' | 'recording' | 'release' | 'release-group' | 'series' | 'work' | 'url';
|
|
241
|
+
export type Relationships = 'area-rels' | 'artist-rels' | 'event-rels' | 'instrument-rels' | 'label-rels' | 'place-rels' | 'recording-rels' | 'release-rels' | 'release-group-rels' | 'series-rels' | 'url-rels' | 'work-rels';
|
|
242
242
|
export declare enum LinkType {
|
|
243
243
|
license = 302,
|
|
244
244
|
production = 256,
|
|
@@ -569,7 +569,7 @@ export interface IBrowseReleasesResult {
|
|
|
569
569
|
'release-offset': number;
|
|
570
570
|
}
|
|
571
571
|
export interface IBrowseReleaseGroupsResult {
|
|
572
|
-
'release-groups':
|
|
572
|
+
'release-groups': IReleaseGroup[];
|
|
573
573
|
'release-group-count': number;
|
|
574
574
|
'release-group-offset': number;
|
|
575
575
|
}
|
package/lib/rate-limiter.js
CHANGED
|
@@ -4,14 +4,14 @@ exports.RateLimiter = void 0;
|
|
|
4
4
|
const Debug = require("debug");
|
|
5
5
|
const debug = Debug('musicbrainz-api:rate-limiter');
|
|
6
6
|
class RateLimiter {
|
|
7
|
+
static sleep(ms) {
|
|
8
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
9
|
+
}
|
|
7
10
|
constructor(period, maxCalls) {
|
|
8
11
|
this.maxCalls = maxCalls;
|
|
9
12
|
this.queue = [];
|
|
10
13
|
this.period = 1000 * period;
|
|
11
14
|
}
|
|
12
|
-
static sleep(ms) {
|
|
13
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
14
|
-
}
|
|
15
15
|
async limit() {
|
|
16
16
|
let now = new Date().getTime();
|
|
17
17
|
const t0 = now - (this.period);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "musicbrainz-api",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "MusicBrainz API client for reading and submitting metadata",
|
|
5
5
|
"main": "lib/musicbrainz-api",
|
|
6
6
|
"types": "lib/musicbrainz-api",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"jsontoxml": "^1.0.1",
|
|
47
47
|
"source-map-support": "^0.5.16",
|
|
48
48
|
"tough-cookie": "^4.0.0",
|
|
49
|
-
"uuid": "^
|
|
49
|
+
"uuid": "^9.0.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/chai": "^4.3.0",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"eslint-plugin-import": "^2.25.4",
|
|
63
63
|
"eslint-plugin-jsdoc": "^39.3.3",
|
|
64
64
|
"eslint-plugin-node": "^11.1.0",
|
|
65
|
-
"eslint-plugin-unicorn": "^
|
|
65
|
+
"eslint-plugin-unicorn": "^44.0.2",
|
|
66
66
|
"mocha": "^9.0.1",
|
|
67
67
|
"nyc": "^15.0.0",
|
|
68
68
|
"remark-cli": "^11.0.0",
|