musicbrainz-api 0.7.2 → 0.10.0

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.
Files changed (34) hide show
  1. package/.idea/$PRODUCT_WORKSPACE_FILE$ +1 -1
  2. package/.idea/misc.xml +6 -0
  3. package/.idea/modules.xml +7 -7
  4. package/.idea/vcs.xml +5 -5
  5. package/README.md +482 -290
  6. package/lib/digest-auth.d.ts +21 -21
  7. package/lib/digest-auth.js +82 -87
  8. package/lib/musicbrainz-api.d.ts +293 -156
  9. package/lib/musicbrainz-api.js +541 -390
  10. package/lib/musicbrainz.types.d.ts +585 -379
  11. package/lib/musicbrainz.types.js +16 -16
  12. package/lib/rate-limiter.d.ts +8 -8
  13. package/lib/rate-limiter.js +31 -31
  14. package/lib/xml/xml-isrc-list.d.ts +17 -17
  15. package/lib/xml/xml-isrc-list.js +22 -22
  16. package/lib/xml/xml-isrc.d.ts +10 -10
  17. package/lib/xml/xml-isrc.js +17 -17
  18. package/lib/xml/xml-metadata.d.ts +6 -6
  19. package/lib/xml/xml-metadata.js +29 -29
  20. package/lib/xml/xml-recording.d.ts +24 -24
  21. package/lib/xml/xml-recording.js +20 -20
  22. package/package.json +104 -98
  23. package/.idea/checkstyle-idea.xml +0 -16
  24. package/.idea/codeStyles/Project.xml +0 -38
  25. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  26. package/.idea/inspectionProfiles/Project_Default.xml +0 -6
  27. package/.idea/shelf/Uncommitted_changes_before_Update_at_6-1-2022_11_38_[Default_Changelist]/shelved.patch +0 -58
  28. package/.idea/shelf/Uncommitted_changes_before_Update_at_6-1-2022_11_38__Default_Changelist_.xml +0 -4
  29. package/.idea/shelf/Uncommitted_changes_before_rebase_[Default_Changelist]/shelved.patch +0 -738
  30. package/.idea/shelf/Uncommitted_changes_before_rebase_[Default_Changelist]1/shelved.patch +0 -0
  31. package/.idea/shelf/Uncommitted_changes_before_rebase__Default_Changelist_.xml +0 -4
  32. package/.idea/workspace.xml +0 -722
  33. package/etc/config.js +0 -32
  34. package/yarn-error.log +0 -3608
package/README.md CHANGED
@@ -1,290 +1,482 @@
1
- [![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)
2
- [![NPM version](https://img.shields.io/npm/v/musicbrainz-api.svg)](https://npmjs.org/package/musicbrainz-api)
3
- [![npm downloads](http://img.shields.io/npm/dm/musicbrainz-api.svg)](https://npmcharts.com/compare/musicbrainz-api)
4
- [![Coverage Status](https://coveralls.io/repos/github/Borewit/musicbrainz-api/badge.svg?branch=master)](https://coveralls.io/github/Borewit/musicbrainz-api?branch=master)
5
- [![Codacy Badge](https://app.codacy.com/project/badge/Grade/2bc47b2006454bae8c737991f152e518)](https://www.codacy.com/gh/Borewit/musicbrainz-api/dashboard?utm_source=github.com&utm_medium=referral&utm_content=Borewit/musicbrainz-api&utm_campaign=Badge_Grade)
6
- [![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/Borewit/musicbrainz-api.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/Borewit/musicbrainz-api/context:javascript)
7
- [![Known Vulnerabilities](https://snyk.io/test/github/Borewit/musicbrainz-api/badge.svg?targetFile=package.json)](https://snyk.io/test/github/Borewit/musicbrainz-api?targetFile=package.json)
8
- [![Total alerts](https://img.shields.io/lgtm/alerts/g/Borewit/musicbrainz-api.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/Borewit/musicbrainz-api/alerts/)
9
- [![DeepScan grade](https://deepscan.io/api/teams/5165/projects/6991/branches/63373/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=5165&pid=6991&bid=63373)
10
- [![Discord](https://img.shields.io/discord/460524735235883049.svg)](https://discord.gg/958xT5X)
11
-
12
- # musicbrainz-api
13
-
14
- A MusicBrainz-API-client for reading and submitting metadata
15
-
16
- ## Features
17
- * Access metadata from MusicBrainz
18
- * Submit metadata
19
- * Smart and adjustable throttling, like MusicBrainz, it allows a bursts of requests
20
- * Build in TypeScript definitions
21
-
22
- ## Before using this library
23
-
24
- MusicBrainz asks that you [identifying your application](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2#User%20Data) by filling in the ['User-Agent' Header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent).
25
- By passing `appName`, `appVersion`, `appMail` musicbrainz-api takes care of that.
26
-
27
- ## Submitting metadata
28
-
29
- If you plan to use this module for submitting metadata, please ensure you comply with [the MusicBrainz Code of conduct/Bots](https://wiki.musicbrainz.org/Code_of_Conduct/Bots).
30
-
31
- ## Example
32
-
33
- Import the module
34
- JavaScript example, how to import 'musicbrainz-api:
35
- ```js
36
- const MusicBrainzApi = require('musicbrainz-api').MusicBrainzApi;
37
-
38
- const mbApi = new MusicBrainzApi({
39
- appName: 'my-app',
40
- appVersion: '0.1.0',
41
- appContactInfo: 'user@mail.org'
42
- });
43
- ```
44
-
45
- In TypeScript you it would look like this:
46
- ```js
47
- import {MusicBrainzApi} from 'musicbrainz-api';
48
-
49
- const mbApi = new MusicBrainzApi({
50
- appName: 'my-app',
51
- appVersion: '0.1.0',
52
- appContactInfo: 'user@mail.org' // Or URL to application home page
53
- });
54
- ```
55
-
56
- The following configuration settings can be passed
57
- ```js
58
- import {MusicBrainzApi} from '../src/musicbrainz-api';
59
-
60
- const config = {
61
- // MusicBrainz bot account username & password (optional)
62
- botAccount: {
63
- username: 'myUserName_bot',
64
- password: 'myPassword'
65
- },
66
-
67
- // API base URL, default: 'https://musicbrainz.org' (optional)
68
- baseUrl: 'https://musicbrainz.org',
69
-
70
- appName: 'my-app',
71
- appVersion: '0.1.0',
72
-
73
- // Optional, default: no proxy server
74
- proxy: {
75
- host: 'localhost',
76
- port: 8888
77
- },
78
-
79
- // Your e-mail address, required for submitting ISRCs
80
- appMail: string
81
- }
82
-
83
- const mbApi = new MusicbrainzApi(config);
84
- ```
85
-
86
- ## Lookup MusicBrainz Entities
87
-
88
- MusicBrainz API documentation: [XML Web Service/Version 2 Lookups](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2#Lookups)
89
-
90
- ### Generic lookup function
91
-
92
- Arguments:
93
- * entity: `'artist'` | `'label'` | `'recording'` | `'release'` | `'release-group'` | `'work'` | `'area'` | `'url'`
94
- * MBID [(MusicBrainz identifier)](https://wiki.musicbrainz.org/MusicBrainz_Identifier)
95
-
96
- ```js
97
- const artist = await mbApi.getEntity('artist', {query: 'ab2528d9-719f-4261-8098-21849222a0f2'});
98
- ```
99
-
100
- ### Lookup area
101
-
102
- ```js
103
- const area = await mbApi.getArea({query: 'ab2528d9-719f-4261-8098-21849222a0f2'});
104
- ```
105
-
106
- ### Lookup artist
107
-
108
- Lookup an `artist` and include their `releases`, `release-groups` and `aliases`
109
-
110
- ```js
111
- const artist = await mbApi.getArtist({query: 'ab2528d9-719f-4261-8098-21849222a0f2'});
112
- ```
113
-
114
- or use the browse API:
115
-
116
- ```js
117
- const artist = await mbApi.getArtist({artist: 'ab2528d9-719f-4261-8098-21849222a0f2'});
118
- ```
119
-
120
- 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:
121
- ```js
122
- const artist = await mbApi.getArtist('ab2528d9-719f-4261-8098-21849222a0f2', ['releases', 'recordings', 'url-rels']);
123
- ```
124
-
125
- ### Lookup recording
126
-
127
- The second argument can be used to pass [subqueries](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2#Subqueries):
128
- ```js
129
- const artist = await mbApi.getRecording({query: '16afa384-174e-435e-bfa3-5591accda31c'}, ['artists', 'url-rels']);
130
- ```
131
-
132
- ### Lookup release
133
- ```js
134
- const release = await mbApi.getRelease({query: '976e0677-a480-4a5e-a177-6a86c1900bbf'}, ['artists', 'url-rels']);
135
- ```
136
-
137
- ### Lookup release-group
138
- ```js
139
- const releaseGroup = await mbApi.getReleaseGroup({query: '19099ea5-3600-4154-b482-2ec68815883e'});
140
- ```
141
-
142
- ### Lookup work
143
- ```js
144
- const work = await mbApi.getWork({query: 'b2aa02f4-6c95-43be-a426-aedb9f9a3805'});
145
- ```
146
-
147
- ## Search (query)
148
-
149
- Implements [XML Web Service/Version 2/Search](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search).
150
-
151
- There are different search fields depending on the entity.
152
-
153
- ### Generic search function
154
-
155
- Searches can be performed using the generic search function: `query(entity: mb.EntityType, query: string | IFormData, offset?: number, limit?: number)`
156
-
157
- Arguments:
158
- * Entity type, which can be one of:
159
- * `artist`: [search fields](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search#Artist)
160
- * `label`: [search fields](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search#Label)
161
- * `recording`: [search fields](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search#Recording)
162
- * `release`: [search fields](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search#Release)
163
- * `release-group`: [search fields](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search#Release_Group)
164
- * `work`: [search fields](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search#Work)
165
- * `area`: [search fields](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search#Area)
166
- * `url`: [search fields](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search#URL)
167
- * `query {query: string, offset: number, limit: number}`
168
- * `query.query`: supports the full Lucene Search syntax; you can find a detailed guide at [Lucene Search Syntax](https://lucene.apache.org/core/4_3_0/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#package_description). For example, you can set conditions while searching for a name with the AND operator.
169
- * `query.offset`: optional, return search results starting at a given offset. Used for paging through more than one page of results.
170
- * `limit.query`: optional, an integer value defining how many entries should be returned. Only values between 1 and 100 (both inclusive) are allowed. If not given, this defaults to 25.
171
-
172
- For example, to find any recordings of _'We Will Rock You'_ by Queen:
173
- ```js
174
- const query = 'query="We Will Rock You" AND arid:0383dadf-2a4e-4d10-a46a-e9e041da8eb3';
175
- const result = await mbApi.query<mb.IReleaseGroupList>('release-group', {query});
176
- ```
177
-
178
- ##### Example: search Île-de-France
179
-
180
- ```js
181
- mbApi.search('area', 'Île-de-France');
182
- ````
183
-
184
- ##### Example: search release by barcode
185
-
186
- Search a release with the barcode 602537479870:
187
- ```js
188
- mbApi.search('release', {query: {barcode: 602537479870}});
189
- ````
190
-
191
- ##### Example: search by object
192
-
193
- Same as previous example, but automatically serialize parameters to search query
194
- ```js
195
- mbApi.search('release', 'barcode: 602537479870');
196
- ````
197
-
198
- ### Entity specific search functions
199
-
200
- The following entity specific search functions are available:
201
- ```TypeScript
202
- searchArtist(query: string | IFormData, offset?: number, limit?: number): Promise<mb.IArtistList>
203
- searchReleaseGroup(query: string | IFormData, offset?: number, limit?: number): Promise<mb.IReleaseGroupList>`
204
- ```
205
-
206
- Search artist:
207
- ```js
208
- const result = await mbApi.searchArtist({query: 'Stromae'});
209
- ```
210
-
211
- Search release-group:
212
- ```js
213
- const result = await mbApi.searchReleaseGroup({query: 'Racine carrée'});
214
- ```
215
-
216
- Search a combination of a release-group and an artist.
217
- ```js
218
- const result = await mbApi.searchReleaseGroup({artist: 'Racine carrée', releasegroup: 'Stromae'});
219
- ```
220
-
221
- # Submitting data via XML POST
222
-
223
- [Submitting data via XML POST](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2#Submitting_data) may be done using personal MusicBrainz credentials.
224
-
225
- ## Submit ISRC code using XML POST
226
-
227
- Using the [XML ISRC submission](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2#ISRC_submission) API.
228
-
229
- ```js
230
- const mbid_Formidable = '16afa384-174e-435e-bfa3-5591accda31c';
231
- const isrc_Formidable = 'BET671300161';
232
-
233
- const xmlMetadata = new XmlMetadata();
234
- const xmlRecording = xmlMetadata.pushRecording(mbid_Formidable);
235
- xmlRecording.isrcList.pushIsrc(isrc_Formidable);
236
- await mbApi.post('recording', xmlMetadata);
237
- ```
238
-
239
- # Submitting data via user form-data
240
-
241
- For all of the following function you need to use a dedicated bot account.
242
-
243
- ## Submitting ISRC via post user form-data
244
-
245
- <img width="150" src="http://www.clker.com/cliparts/i/w/L/q/u/1/work-in-progress.svg"/>
246
- Use with caution, and only on a test server, it may clear existing metadata as side effect.
247
-
248
- ```js
249
-
250
- const mbid_Formidable = '16afa384-174e-435e-bfa3-5591accda31c';
251
- const isrc_Formidable = 'BET671300161';
252
-
253
-
254
- const recording = await mbApi.getRecording(mbid_Formidable);
255
-
256
- // Authentication the http-session against MusicBrainz (as defined in config.baseUrl)
257
- const succeed = await mbApi.login();
258
- assert.isTrue(succeed, 'Login successful');
259
-
260
- // To submit the ISRC, the `recording.id` and `recording.title` are required
261
- await mbApi.addIsrc(recording, isrc_Formidable);
262
- ```
263
-
264
- ### Submit recording URL
265
-
266
- ```js
267
- const recording = await mbApi.getRecording('16afa384-174e-435e-bfa3-5591accda31c');
268
-
269
- const succeed = await mbApi.login();
270
- assert.isTrue(succeed, 'Login successful');
271
-
272
- await mbApi.addUrlToRecording(recording, {
273
- linkTypeId: LinkType.stream_for_free,
274
- text: 'https://open.spotify.com/track/2AMysGXOe0zzZJMtH3Nizb'
275
- });
276
- ```
277
-
278
- Actually a Spotify-track-ID can be submitted easier:
279
- ```js
280
- const recording = await mbApi.getRecording('16afa384-174e-435e-bfa3-5591accda31c');
281
-
282
- const succeed = await mbApi.login();
283
- assert.isTrue(succeed, 'Login successful');
284
- await mbApi.addSpotifyIdToRecording(recording, '2AMysGXOe0zzZJMtH3Nizb');
285
- ```
286
-
287
- ## Compatibility
288
-
289
- The JavaScript in runtime is compliant with [ECMAScript 2017 (ES8)](https://en.wikipedia.org/wiki/ECMAScript#8th_Edition_-_ECMAScript_2017).
290
- Requires [Node.js®](https://nodejs.org/) version 6 or higher.
1
+ [![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)
2
+ [![NPM version](https://img.shields.io/npm/v/musicbrainz-api.svg)](https://npmjs.org/package/musicbrainz-api)
3
+ [![npm downloads](http://img.shields.io/npm/dm/musicbrainz-api.svg)](https://npmcharts.com/compare/musicbrainz-api)
4
+ [![Coverage Status](https://coveralls.io/repos/github/Borewit/musicbrainz-api/badge.svg?branch=master)](https://coveralls.io/github/Borewit/musicbrainz-api?branch=master)
5
+ [![Codacy Badge](https://app.codacy.com/project/badge/Grade/2bc47b2006454bae8c737991f152e518)](https://www.codacy.com/gh/Borewit/musicbrainz-api/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=Borewit/musicbrainz-api&amp;utm_campaign=Badge_Grade)
6
+ [![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/Borewit/musicbrainz-api.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/Borewit/musicbrainz-api/context:javascript)
7
+ [![Known Vulnerabilities](https://snyk.io/test/github/Borewit/musicbrainz-api/badge.svg?targetFile=package.json)](https://snyk.io/test/github/Borewit/musicbrainz-api?targetFile=package.json)
8
+ [![Total alerts](https://img.shields.io/lgtm/alerts/g/Borewit/musicbrainz-api.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/Borewit/musicbrainz-api/alerts/)
9
+ [![DeepScan grade](https://deepscan.io/api/teams/5165/projects/6991/branches/63373/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=5165&pid=6991&bid=63373)
10
+ [![Discord](https://img.shields.io/discord/460524735235883049.svg)](https://discord.gg/958xT5X)
11
+
12
+ # musicbrainz-api
13
+
14
+ A MusicBrainz-API-client for reading and submitting metadata
15
+
16
+ ## Features
17
+ * Access metadata from MusicBrainz
18
+ * Submit metadata
19
+ * Smart and adjustable throttling, like MusicBrainz, it allows a bursts of requests
20
+ * Build in TypeScript definitions
21
+
22
+ ## Before using this library
23
+
24
+ MusicBrainz asks that you [identifying your application](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2#User%20Data) by filling in the ['User-Agent' Header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent).
25
+ By passing `appName`, `appVersion`, `appMail` musicbrainz-api takes care of that.
26
+
27
+ ## Submitting metadata
28
+
29
+ If you plan to use this module for submitting metadata, please ensure you comply with [the MusicBrainz Code of conduct/Bots](https://wiki.musicbrainz.org/Code_of_Conduct/Bots).
30
+
31
+ ## Example
32
+
33
+ Import the module
34
+ JavaScript example, how to import 'musicbrainz-api:
35
+ ```js
36
+ const MusicBrainzApi = require('musicbrainz-api').MusicBrainzApi;
37
+
38
+ const mbApi = new MusicBrainzApi({
39
+ appName: 'my-app',
40
+ appVersion: '0.1.0',
41
+ appContactInfo: 'user@mail.org'
42
+ });
43
+ ```
44
+
45
+ In TypeScript you it would look like this:
46
+ ```js
47
+ import {MusicBrainzApi} from 'musicbrainz-api';
48
+
49
+ const mbApi = new MusicBrainzApi({
50
+ appName: 'my-app',
51
+ appVersion: '0.1.0',
52
+ appContactInfo: 'user@mail.org' // Or URL to application home page
53
+ });
54
+ ```
55
+
56
+ The following configuration settings can be passed
57
+ ```js
58
+ import {MusicBrainzApi} from '../src/musicbrainz-api';
59
+
60
+ const config = {
61
+ // MusicBrainz bot account username & password (optional)
62
+ botAccount: {
63
+ username: 'myUserName_bot',
64
+ password: 'myPassword'
65
+ },
66
+
67
+ // API base URL, default: 'https://musicbrainz.org' (optional)
68
+ baseUrl: 'https://musicbrainz.org',
69
+
70
+ appName: 'my-app',
71
+ appVersion: '0.1.0',
72
+
73
+ // Optional, default: no proxy server
74
+ proxy: {
75
+ host: 'localhost',
76
+ port: 8888
77
+ },
78
+
79
+ // Your e-mail address, required for submitting ISRCs
80
+ appMail: string
81
+ }
82
+
83
+ const mbApi = new MusicbrainzApi(config);
84
+ ```
85
+
86
+ ## Lookup MusicBrainz Entities
87
+
88
+ MusicBrainz API documentation: [XML Web Service/Version 2 Lookups](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2#Lookups)
89
+
90
+ ### Generic lookup function
91
+
92
+ Arguments:
93
+ * entity: `'artist'` | `'label'` | `'recording'` | `'release'` | `'release-group'` | `'work'` | `'area'` | `'url'`
94
+ * MBID [(MusicBrainz identifier)](https://wiki.musicbrainz.org/MusicBrainz_Identifier)
95
+
96
+ ```js
97
+ const artist = await mbApi.lookupEntity('artist', {query: 'ab2528d9-719f-4261-8098-21849222a0f2'});
98
+ ```
99
+
100
+ ### Lookup area
101
+
102
+ ```js
103
+ const area = await mbApi.lookupArea({query: 'ab2528d9-719f-4261-8098-21849222a0f2'});
104
+ ```
105
+
106
+ ### Lookup artist
107
+
108
+ Lookup an `artist` and include their `releases`, `release-groups` and `aliases`
109
+
110
+ ```js
111
+ const artist = await mbApi.lookupArtist({query: 'ab2528d9-719f-4261-8098-21849222a0f2'});
112
+ ```
113
+
114
+ ### Lookup instrument
115
+
116
+ Lookup an instrument
117
+
118
+ ```js
119
+ const artist = await mbApi.lookupInstrument({query: 'b3eac5f9-7859-4416-ac39-7154e2e8d348'});
120
+ ```
121
+
122
+ ### Lookup label
123
+
124
+ Lookup a label
125
+
126
+ ```js
127
+ const artist = await mbApi.lookupInstrument({query: '25dda9f9-f069-4898-82f0-59330a106c7f'});
128
+ ```
129
+
130
+ ### Lookup place
131
+
132
+ ```js
133
+ const artist = await mbApi.lookupPlace({query: 'e6cfb74d-d69b-44c3-b890-1b3f509816e4'});
134
+ ```
135
+
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:
137
+ ```js
138
+ const artist = await mbApi.lookupArtist('ab2528d9-719f-4261-8098-21849222a0f2', ['releases', 'recordings', 'url-rels']);
139
+ ```
140
+
141
+ ### Lookup recording
142
+
143
+ The second argument can be used to pass [subqueries](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2#Subqueries):
144
+ ```js
145
+ const artist = await mbApi.lookupRecording({query: '16afa384-174e-435e-bfa3-5591accda31c'}, ['artists', 'url-rels']);
146
+ ```
147
+
148
+ ### Lookup release
149
+ ```js
150
+ const release = await mbApi.lookupRelease({query: '976e0677-a480-4a5e-a177-6a86c1900bbf'}, ['artists', 'url-rels']);
151
+ ```
152
+
153
+ ### Lookup release-group
154
+ ```js
155
+ const releaseGroup = await mbApi.lookupReleaseGroup({query: '19099ea5-3600-4154-b482-2ec68815883e'});
156
+ ```
157
+
158
+ ### Lookup work
159
+ ```js
160
+ const work = await mbApi.lookupWork({query: 'b2aa02f4-6c95-43be-a426-aedb9f9a3805'});
161
+ ```
162
+
163
+ ### Lookup URL
164
+ ```js
165
+ const url = await mbApi.lookupUrl({query: 'c69556a6-7ded-4c54-809c-afb45a1abe7d'});
166
+ ```
167
+
168
+ ### Lookup URL
169
+ ```js
170
+ const url = await mbApi.lookupUrl({query: 'c69556a6-7ded-4c54-809c-afb45a1abe7d'});
171
+ ```
172
+
173
+ ## Browse entities
174
+
175
+ ### Browse area
176
+
177
+ ```js
178
+ const area = await browseAreas(query);
179
+ ````
180
+
181
+ | Query argument | Query value |
182
+ |-----------------------|-----------------|
183
+ | `query.collection` | Collection MBID |
184
+
185
+ ### Browse artist
186
+
187
+ ```js
188
+ const artist = await browseArtist(query);
189
+ ````
190
+
191
+ | Query argument | Query value |
192
+ |-----------------------|--------------------|
193
+ | `query.area` | Area MBID |
194
+ | `query.collection` | Collection MBID |
195
+ | `query.recording` | Recording MBID |
196
+ | `query.release` | Release MBID |
197
+ | `query.release-group` | Release-group MBID |
198
+ | `query.work` | Work MBID |
199
+
200
+ ### Browse collection
201
+ ```js
202
+ const artist = await browseCollection(query);
203
+ ````
204
+
205
+ | Query argument | Query value |
206
+ |-----------------------|--------------------|
207
+ | `query.area` | Area MBID |
208
+ | `query.artist` | Artist MBID |
209
+ | `query.editor` | Editor MBID |
210
+ | `query.event` | Event MBID |
211
+ | `query.label` | Label MBID |
212
+ | `query.place` | Place MBID |
213
+ | `query.recording` | Recording MBID |
214
+ | `query.release` | Release MBID |
215
+ | `query.release-group` | Release-group MBID |
216
+ | `query.work` | Work MBID |
217
+
218
+ ### Browse events
219
+ ```js
220
+ const events = await browseEvents(query);
221
+ ````
222
+
223
+ | Query argument | Query value |
224
+ |-----------------------|-----------------|
225
+ | `query.area` | Area MBID |
226
+ | `query.artist` | Artist MBID |
227
+ | `query.collection` | Collection MBID |
228
+ | `query.place` | Place MBID |
229
+
230
+ ### Browse instruments
231
+ ```js
232
+ const instruments = await browseEvents(query);
233
+ ````
234
+
235
+ | Query argument | Query value |
236
+ |-----------------------|--------------------|
237
+ | `query.collection` | Collection MBID |
238
+
239
+ ### Browse labels
240
+ ```js
241
+ const labels = await browseLabels(query);
242
+ ````
243
+
244
+ | Query argument | Query value |
245
+ |--------------------|-----------------|
246
+ | `query.area` | Area MBID |
247
+ | `query.collection` | Collection MBID |
248
+ | `query.release` | Release MBID |
249
+
250
+ ### Browse places
251
+ ```js
252
+ const places = await browsePlaces(query);
253
+ ````
254
+
255
+ | Query argument | Query value |
256
+ |--------------------|-----------------|
257
+ | `query.area` | Area MBID |
258
+ | `query.collection` | Collection MBID |
259
+
260
+ ### Browse recordings
261
+ ```js
262
+ const recordings = await browseRecordings(query);
263
+ ````
264
+
265
+ | Query argument | Query value |
266
+ |--------------------|-----------------|
267
+ | `query.artist` | Area MBID |
268
+ | `query.collection` | Collection MBID |
269
+ | `query.release` | Release MBID |
270
+ | `query.work` | Work MBID |
271
+
272
+ ### Browse releases
273
+ ```js
274
+ const places = await browseReleases(query);
275
+ ````
276
+
277
+ | Query argument | Query value |
278
+ |-----------------------|--------------------|
279
+ | `query.area` | Area MBID |
280
+ | `query.artist` | Artist MBID |
281
+ | `query.editor` | Editor MBID |
282
+ | `query.event` | Event MBID |
283
+ | `query.label` | Label MBID |
284
+ | `query.place` | Place MBID |
285
+ | `query.recording` | Recording MBID |
286
+ | `query.release` | Release MBID |
287
+ | `query.release-group` | Release-group MBID |
288
+ | `query.work` | Work MBID |
289
+
290
+ ### Browse release-groups
291
+ ```js
292
+ const places = await browseReleaseGroups(query);
293
+ ```
294
+
295
+ | Query argument | Query value |
296
+ |--------------------|-----------------|
297
+ | `query.artist` | Artist MBID |
298
+ | `query.collection` | Collection MBID |
299
+ | `query.release` | Release MBID |
300
+
301
+ ### Browse series
302
+ ```js
303
+ const places = await browseSeries();
304
+ ````
305
+
306
+ | Query argument | Query value |
307
+ |-----------------------|--------------------|
308
+ | `query.area` | Area MBID |
309
+ | `query.artist` | Artist MBID |
310
+ | `query.editor` | Editor MBID |
311
+ | `query.event` | Event MBID |
312
+ | `query.label` | Label MBID |
313
+ | `query.place` | Place MBID |
314
+ | `query.recording` | Recording MBID |
315
+ | `query.release` | Release MBID |
316
+ | `query.release-group` | Release-group MBID |
317
+ | `query.work` | Work MBID |
318
+
319
+ ### Browse works
320
+ ```js
321
+ const places = await browseWorks();
322
+ ````
323
+
324
+ | Query argument | Query value |
325
+ |--------------------|-----------------|
326
+ | `query.artist` | Artist MBID |
327
+ | `query.xollection` | Collection MBID |
328
+
329
+ ### Browse urls
330
+ ```js
331
+ const urls = await browseUrls();
332
+ ````
333
+
334
+ | Query argument | Query value |
335
+ |--------------------|-----------------|
336
+ | `query.artist` | Artist MBID |
337
+ | `query.xollection` | Collection MBID |
338
+
339
+ ## Search (query)
340
+
341
+ Implements [XML Web Service/Version 2/Search](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search).
342
+
343
+ There are different search fields depending on the entity.
344
+
345
+ ### Generic search function
346
+
347
+ Searches can be performed using the generic search function: `query(entity: mb.EntityType, query: string | IFormData, offset?: number, limit?: number)`
348
+
349
+ Arguments:
350
+ * Entity type, which can be one of:
351
+ * `artist`: [search fields](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search#Artist)
352
+ * `label`: [search fields](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search#Label)
353
+ * `recording`: [search fields](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search#Recording)
354
+ * `release`: [search fields](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search#Release)
355
+ * `release-group`: [search fields](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search#Release_Group)
356
+ * `work`: [search fields](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search#Work)
357
+ * `area`: [search fields](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search#Area)
358
+ * `url`: [search fields](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2/Search#URL)
359
+ * `query {query: string, offset: number, limit: number}`
360
+ * `query.query`: supports the full Lucene Search syntax; you can find a detailed guide at [Lucene Search Syntax](https://lucene.apache.org/core/4_3_0/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#package_description). For example, you can set conditions while searching for a name with the AND operator.
361
+ * `query.offset`: optional, return search results starting at a given offset. Used for paging through more than one page of results.
362
+ * `limit.query`: optional, an integer value defining how many entries should be returned. Only values between 1 and 100 (both inclusive) are allowed. If not given, this defaults to 25.
363
+
364
+ For example, to find any recordings of _'We Will Rock You'_ by Queen:
365
+ ```js
366
+ const query = 'query="We Will Rock You" AND arid:0383dadf-2a4e-4d10-a46a-e9e041da8eb3';
367
+ const result = await mbApi.query<mb.IReleaseGroupList>('release-group', {query});
368
+ ```
369
+
370
+ ##### Example: search Île-de-France
371
+
372
+ ```js
373
+ mbApi.search('area', 'Île-de-France');
374
+ ````
375
+
376
+ ##### Example: search release by barcode
377
+
378
+ Search a release with the barcode 602537479870:
379
+ ```js
380
+ mbApi.search('release', {query: {barcode: 602537479870}});
381
+ ````
382
+
383
+ ##### Example: search by object
384
+
385
+ Same as previous example, but automatically serialize parameters to search query
386
+ ```js
387
+ mbApi.search('release', 'barcode: 602537479870');
388
+ ````
389
+
390
+ ### Entity specific search functions
391
+
392
+ The following entity specific search functions are available:
393
+ ```TypeScript
394
+ searchArtist(query: string | IFormData, offset?: number, limit?: number): Promise<mb.IArtistList>
395
+ searchReleaseGroup(query: string | IFormData, offset?: number, limit?: number): Promise<mb.IReleaseGroupList>`
396
+ ```
397
+
398
+ Search artist:
399
+ ```js
400
+ const result = await mbApi.searchArtist({query: 'Stromae'});
401
+ ```
402
+
403
+ Search release-group:
404
+ ```js
405
+ const result = await mbApi.searchReleaseGroup({query: 'Racine carrée'});
406
+ ```
407
+
408
+ Search a combination of a release-group and an artist.
409
+ ```js
410
+ const result = await mbApi.searchReleaseGroup({artist: 'Racine carrée', releasegroup: 'Stromae'});
411
+ ```
412
+
413
+ # Submitting data via XML POST
414
+
415
+ [Submitting data via XML POST](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2#Submitting_data) may be done using personal MusicBrainz credentials.
416
+
417
+ ## Submit ISRC code using XML POST
418
+
419
+ Using the [XML ISRC submission](https://wiki.musicbrainz.org/Development/XML_Web_Service/Version_2#ISRC_submission) API.
420
+
421
+ ```js
422
+ const mbid_Formidable = '16afa384-174e-435e-bfa3-5591accda31c';
423
+ const isrc_Formidable = 'BET671300161';
424
+
425
+ const xmlMetadata = new XmlMetadata();
426
+ const xmlRecording = xmlMetadata.pushRecording(mbid_Formidable);
427
+ xmlRecording.isrcList.pushIsrc(isrc_Formidable);
428
+ await mbApi.post('recording', xmlMetadata);
429
+ ```
430
+
431
+ # Submitting data via user form-data
432
+
433
+ For all of the following function you need to use a dedicated bot account.
434
+
435
+ ## Submitting ISRC via post user form-data
436
+
437
+ <img width="150" src="http://www.clker.com/cliparts/i/w/L/q/u/1/work-in-progress.svg"/>
438
+ Use with caution, and only on a test server, it may clear existing metadata as side effect.
439
+
440
+ ```js
441
+
442
+ const mbid_Formidable = '16afa384-174e-435e-bfa3-5591accda31c';
443
+ const isrc_Formidable = 'BET671300161';
444
+
445
+
446
+ const recording = await mbApi.lookupRecording(mbid_Formidable);
447
+
448
+ // Authentication the http-session against MusicBrainz (as defined in config.baseUrl)
449
+ const succeed = await mbApi.login();
450
+ assert.isTrue(succeed, 'Login successful');
451
+
452
+ // To submit the ISRC, the `recording.id` and `recording.title` are required
453
+ await mbApi.addIsrc(recording, isrc_Formidable);
454
+ ```
455
+
456
+ ### Submit recording URL
457
+
458
+ ```js
459
+ const recording = await mbApi.lookupRecording('16afa384-174e-435e-bfa3-5591accda31c');
460
+
461
+ const succeed = await mbApi.login();
462
+ assert.isTrue(succeed, 'Login successful');
463
+
464
+ await mbApi.addUrlToRecording(recording, {
465
+ linkTypeId: LinkType.stream_for_free,
466
+ text: 'https://open.spotify.com/track/2AMysGXOe0zzZJMtH3Nizb'
467
+ });
468
+ ```
469
+
470
+ Actually a Spotify-track-ID can be submitted easier:
471
+ ```js
472
+ const recording = await mbApi.lookupRecording('16afa384-174e-435e-bfa3-5591accda31c');
473
+
474
+ const succeed = await mbApi.login();
475
+ assert.isTrue(succeed, 'Login successful');
476
+ await mbApi.addSpotifyIdToRecording(recording, '2AMysGXOe0zzZJMtH3Nizb');
477
+ ```
478
+
479
+ ## Compatibility
480
+
481
+ The JavaScript in runtime is compliant with [ECMAScript 2017 (ES8)](https://en.wikipedia.org/wiki/ECMAScript#8th_Edition_-_ECMAScript_2017).
482
+ Requires [Node.js®](https://nodejs.org/) version 6 or higher.