diff --git a/node_modules/musicbrainz-api/lib/http-client.js b/node_modules/musicbrainz-api/lib/http-client.js index a5ca5f7..f693ca3 100644 --- a/node_modules/musicbrainz-api/lib/http-client.js +++ b/node_modules/musicbrainz-api/lib/http-client.js @@ -9,6 +9,7 @@ function isConnectionReset(err) { export class HttpClient { constructor(httpOptions) { this.httpOptions = httpOptions; + this.preRequest = (httpOptions ?? {}).preRequest } get(path, options) { return this._fetch('get', path, options); @@ -29,18 +30,25 @@ export class HttpClient { options = {}; let retryLimit = options.retryLimit && options.retryLimit > 1 ? options.retryLimit : 1; const retryTimeout = this.httpOptions.timeout ? this.httpOptions.timeout : 500; - const url = this._buildUrl(path, options.query); + let url = this._buildUrl(path, options.query); const cookies = await this.getCookies(); - const headers = new Headers(options.headers); + let headers = new Headers(options.headers); headers.set('User-Agent', this.httpOptions.userAgent); if (cookies !== null) { headers.set('Cookie', cookies); } + if(this.preRequest !== undefined) { + const [m, u, h] = this.preRequest(method, url, headers); + url = u; + headers = h; + } + let signal = this.httpOptions.requestTimeout !== undefined ? AbortSignal.timeout(this.httpOptions.requestTimeout) : undefined; while (retryLimit > 0) { let response; try { response = await fetch(url, { method, + signal, ...options, headers, body: options.body, @@ -56,8 +64,8 @@ export class HttpClient { throw err; } if (response.status === 429 || response.status === 503) { - debug(`Received status=${response.status}, assume reached rate limit, retry in ${retryTimeout} ms`); retryLimit--; + debug(`Received status=${response.status}, assume reached rate limit, retry in ${retryTimeout} ms with limit decreased to ${retryLimit}`); if (retryLimit > 0) { await this._delay(retryTimeout); // wait 200ms before retry continue; diff --git a/node_modules/musicbrainz-api/lib/musicbrainz-api-node.js b/node_modules/musicbrainz-api/lib/musicbrainz-api-node.js index c9cad5a..226cd5e 100644 --- a/node_modules/musicbrainz-api/lib/musicbrainz-api-node.js +++ b/node_modules/musicbrainz-api/lib/musicbrainz-api-node.js @@ -15,7 +15,9 @@ export class MusicBrainzApi extends MusicBrainzApiDefault { return new HttpClientNode({ baseUrl: this.config.baseUrl, timeout: 500, - userAgent: `${this.config.appName}/${this.config.appVersion} ( ${this.config.appContactInfo} )` + userAgent: `${this.config.appName}/${this.config.appVersion} ( ${this.config.appContactInfo} )`, + preRequest: this.config.preRequest, + requestTimeout: this.config.requestTimeout }); } async login() { diff --git a/node_modules/musicbrainz-api/lib/musicbrainz-api.d.ts b/node_modules/musicbrainz-api/lib/musicbrainz-api.d.ts index cd05017..4664ff0 100644 --- a/node_modules/musicbrainz-api/lib/musicbrainz-api.d.ts +++ b/node_modules/musicbrainz-api/lib/musicbrainz-api.d.ts @@ -2,6 +2,7 @@ import type { XmlMetadata } from './xml/xml-metadata.js'; import { RateLimitThreshold } from 'rate-limit-threshold'; import * as mb from './musicbrainz.types.js'; import { HttpClient, type MultiQueryFormData } from "./http-client.js"; +import { Url } from 'node:url'; export { XmlMetadata } from './xml/xml-metadata.js'; export { XmlIsrc } from './xml/xml-isrc.js'; export { XmlIsrcList } from './xml/xml-isrc-list.js'; @@ -75,6 +76,9 @@ export interface IMusicBrainzConfig { * Default is [15, 18], which allows up to 15 requests every 18 seconds */ rateLimit?: [number, number]; + preRequest?: (method: string, url: string, headers: Headers) => [string,string,Headers] + requestTimeout?: number + retryLimit?: number } interface IInternalConfig extends IMusicBrainzConfig { baseUrl: string; diff --git a/node_modules/musicbrainz-api/lib/musicbrainz-api.js b/node_modules/musicbrainz-api/lib/musicbrainz-api.js index 72fb15d..f6bdfe5 100644 --- a/node_modules/musicbrainz-api/lib/musicbrainz-api.js +++ b/node_modules/musicbrainz-api/lib/musicbrainz-api.js @@ -38,12 +38,15 @@ export class MusicBrainzApi { this.httpClient = this.initHttpClient(); const limits = this.config.rateLimit ?? [15, 18]; this.rateLimiter = new RateLimitThreshold(limits[0], limits[1]); + this.retryLimit = this.config.retryLimit ?? 10; } initHttpClient() { return new HttpClient({ baseUrl: this.config.baseUrl, timeout: 500, - userAgent: `${this.config.appName}/${this.config.appVersion} ( ${this.config.appContactInfo} )` + userAgent: `${this.config.appName}/${this.config.appVersion} ( ${this.config.appContactInfo} )`, + preRequest: this.config.preRequest, + requestTimeout: this.config.requestTimeout }); } async restGet(relUrl, query = {}) { @@ -51,7 +54,7 @@ export class MusicBrainzApi { await this.applyRateLimiter(); const response = await this.httpClient.get(`/ws/2${relUrl}`, { query, - retryLimit: 10 + retryLimit: this.retryLimit }); return response.json(); } diff --git a/node_modules/musicbrainz-api/lib/musicbrainz.types.d.ts b/node_modules/musicbrainz-api/lib/musicbrainz.types.d.ts index 1ebc7b2..e004b9b 100644 --- a/node_modules/musicbrainz-api/lib/musicbrainz.types.d.ts +++ b/node_modules/musicbrainz-api/lib/musicbrainz.types.d.ts @@ -156,7 +156,8 @@ export interface IMedium { title: string; format?: string; 'format-id': string; - tracks: ITrack[]; + tracks?: ITrack[]; + track?: ITrack[] 'track-count': number; 'track-offset': number; position: number;