lavalink-client 2.10.0 → 2.10.2

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/dist/index.js CHANGED
@@ -421,8 +421,6 @@ var DefaultSources = {
421
421
  pandora: "pdsearch",
422
422
  pd: "pdsearch",
423
423
  pdsearch: "pdsearch",
424
- pdisrc: "pdisrc",
425
- pdrec: "pdrec",
426
424
  "pandora music": "pdsearch",
427
425
  pandoramusic: "pdsearch",
428
426
  // speak PLUGIN
@@ -457,7 +455,15 @@ var DefaultSources = {
457
455
  jiosaavn: "jssearch",
458
456
  js: "jssearch",
459
457
  jssearch: "jssearch",
460
- jsrec: "jsrec"
458
+ jsrec: "jsrec",
459
+ // amazon music
460
+ amzsearch: "amzsearch",
461
+ // audiomack
462
+ admsearch: "admsearch",
463
+ // gaana
464
+ gnsearch: "gnsearch",
465
+ // shazam
466
+ szsearch: "szsearch"
461
467
  };
462
468
  var LavalinkPlugins = {
463
469
  DuncteBot_Plugin: "DuncteBot-plugin",
@@ -466,7 +472,8 @@ var LavalinkPlugins = {
466
472
  LavaSearch: "lavasearch-plugin",
467
473
  Jiosaavn_Plugin: "jiosaavn-plugin",
468
474
  LavalinkFilterPlugin: "lavalink-filter-plugin",
469
- JavaTimedLyricsPlugin: "java-lyrics-plugin"
475
+ JavaTimedLyricsPlugin: "java-lyrics-plugin",
476
+ PulseLinkPlugin: "pulselink-plugin"
470
477
  };
471
478
  var SourceLinksRegexes = {
472
479
  /** DEFAULT SUPPORTED BY LAVALINK */
@@ -542,6 +549,8 @@ function parseLavalinkConnUrl(connectionUrl) {
542
549
  }
543
550
  var ManagerUtils = class {
544
551
  LavalinkManager = void 0;
552
+ /** Override this with your custom sources record if you want to use custom sources for your node */
553
+ SourcesRecord = DefaultSources;
545
554
  constructor(LavalinkManager2) {
546
555
  this.LavalinkManager = LavalinkManager2;
547
556
  }
@@ -869,13 +878,13 @@ var ManagerUtils = class {
869
878
  return;
870
879
  }
871
880
  /**
872
- * Finds the source of a query string by checking if it starts with a valid source prefix defined in the DefaultSources object. If a valid source prefix is found, it returns the corresponding SearchPlatform; otherwise, it returns null. This function is useful for determining the intended search platform for a given query string, allowing for more accurate search results when the user specifies a source (e.g., "ytsearch:Never Gonna Give You Up" would indicate that the search should be performed on YouTube).
881
+ * Finds the source of a query string by checking if it starts with a valid source prefix defined in the Default Sources object. If a valid source prefix is found, it returns the corresponding SearchPlatform; otherwise, it returns null. This function is useful for determining the intended search platform for a given query string, allowing for more accurate search results when the user specifies a source (e.g., "ytsearch:Never Gonna Give You Up" would indicate that the search should be performed on YouTube).
873
882
  * @param queryString
874
883
  * @returns
875
884
  */
876
885
  findSourceOfQuery(queryString) {
877
- const foundSource = Object.keys(DefaultSources).find((source) => queryString?.toLowerCase?.()?.startsWith(`${source}:`.toLowerCase()))?.trim?.()?.toLowerCase?.();
878
- if (foundSource && !["https", "http"].includes(foundSource) && DefaultSources[foundSource]) {
886
+ const foundSource = Object.keys(this.SourcesRecord).find((source) => queryString?.toLowerCase?.()?.startsWith(`${source}:`.toLowerCase()))?.trim?.()?.toLowerCase?.();
887
+ if (foundSource && !["https", "http"].includes(foundSource) && this.SourcesRecord[foundSource]) {
879
888
  return foundSource;
880
889
  }
881
890
  return null;
@@ -888,7 +897,7 @@ var ManagerUtils = class {
888
897
  extractSourceOfQuery(searchQuery) {
889
898
  const foundSource = this.findSourceOfQuery(searchQuery.query);
890
899
  if (foundSource) {
891
- searchQuery.source = DefaultSources[foundSource];
900
+ searchQuery.source = this.SourcesRecord[foundSource];
892
901
  searchQuery.query = searchQuery.query.slice(`${foundSource}:`.length, searchQuery.query.length);
893
902
  }
894
903
  return searchQuery;
@@ -919,7 +928,7 @@ var ManagerUtils = class {
919
928
  return this.extractSourceOfQuery(Query);
920
929
  }
921
930
  const providedSource = query?.source?.trim?.()?.toLowerCase?.();
922
- const validSourceExtracted = DefaultSources[providedSource ?? typedDefault];
931
+ const validSourceExtracted = this.SourcesRecord[providedSource ?? typedDefault];
923
932
  return this.extractSourceOfQuery({
924
933
  query: query.query,
925
934
  extraQueryUrlParams: query.extraQueryUrlParams,
@@ -943,7 +952,7 @@ var ManagerUtils = class {
943
952
  return this.extractSourceOfQuery(Query2);
944
953
  }
945
954
  const providedSource = query?.source?.trim?.()?.toLowerCase?.();
946
- const validSourceExtracted = DefaultSources[providedSource ?? typedDefault];
955
+ const validSourceExtracted = this.SourcesRecord[providedSource ?? typedDefault];
947
956
  const Query = {
948
957
  query: query.query,
949
958
  types: query.types ? ["track", "playlist", "artist", "album", "text"].filter(
@@ -967,7 +976,7 @@ var ManagerUtils = class {
967
976
  */
968
977
  validateSourceString(node, sourceString) {
969
978
  if (!sourceString) throw new Error(`No SourceString was provided`);
970
- const source = DefaultSources[sourceString.toLowerCase().trim()];
979
+ const source = this.SourcesRecord[sourceString.toLowerCase().trim()];
971
980
  if (!source && !!this.LavalinkManager.options.playerOptions.allowCustomSources)
972
981
  throw new Error(
973
982
  `Lavalink-Client does not support SearchQuerySource: '${sourceString}'. You can disable this check by setting 'ManagerOptions.PlayerOptions.allowCustomSources' to true`
@@ -1045,6 +1054,18 @@ var ManagerUtils = class {
1045
1054
  if (["pdsearch", "pdisrc", "pdrec"].includes(source) && !node.info?.sourceManagers?.includes("pandora")) {
1046
1055
  throw new Error("Lavalink Node has not 'pandora' enabled, which is required to have '" + source + "' work");
1047
1056
  }
1057
+ if (source === "amzsearch" && !node.info?.sourceManagers?.includes("amazonmusic")) {
1058
+ throw new Error("Lavalink Node has not 'amazonmusic' enabled, which is required to have 'amzsearch' work");
1059
+ }
1060
+ if (source === "admsearch" && !node.info?.sourceManagers?.includes("audiomack")) {
1061
+ throw new Error("Lavalink Node has not 'audiomack' enabled, which is required to have 'admsearch' work");
1062
+ }
1063
+ if (source === "gnsearch" && !node.info?.sourceManagers?.includes("gaana")) {
1064
+ throw new Error("Lavalink Node has not 'gaana' enabled, which is required to have 'gnsearch' work");
1065
+ }
1066
+ if (source === "szsearch" && !node.info?.sourceManagers?.includes("shazam")) {
1067
+ throw new Error("Lavalink Node has not 'shazam' enabled, which is required to have 'szsearch' work");
1068
+ }
1048
1069
  return;
1049
1070
  }
1050
1071
  };
@@ -1367,8 +1388,10 @@ var LavalinkNode = class _LavalinkNode {
1367
1388
  path: `/${this.version}/${endpoint.startsWith("/") ? endpoint.slice(1) : endpoint}`,
1368
1389
  method: "GET",
1369
1390
  headers: {
1370
- Authorization: this.options.authorization
1391
+ Authorization: this.options.authorization,
1392
+ ...this.NodeManager.LavalinkManager?.options?.httpHeaders
1371
1393
  },
1394
+ // if httpHeaders is undefined/null, it won't be added, so we can keept it short like this
1372
1395
  signal: this.options.requestSignalTimeoutMS && this.options.requestSignalTimeoutMS > 0 ? AbortSignal.timeout(this.options.requestSignalTimeoutMS) : void 0
1373
1396
  };
1374
1397
  modify?.(options);
@@ -1481,10 +1504,8 @@ var LavalinkNode = class _LavalinkNode {
1481
1504
  if (Query.source) this._LManager.utils.validateSourceString(this, Query.source);
1482
1505
  if (/^https?:\/\//.test(Query.query))
1483
1506
  return this.search({ query: Query.query, source: Query.source }, requestUser);
1484
- if (!["spsearch", "sprec", "amsearch", "dzsearch", "dzisrc", "ytmsearch", "ytsearch"].includes(Query.source))
1485
- throw new SyntaxError(
1486
- `Query.source must be a source from LavaSrc: "spsearch" | "sprec" | "amsearch" | "dzsearch" | "dzisrc" | "ytmsearch" | "ytsearch"`
1487
- );
1507
+ if (!this.isLavaSrcSource(Query.source))
1508
+ throw new SyntaxError(`Query.source must be an available source from LavaSrc`);
1488
1509
  if (this._checkForPlugins && !this.info?.plugins?.find?.((v) => v.name === "lavasearch-plugin"))
1489
1510
  throw new RangeError(`there is no lavasearch-plugin available in the lavalink node: ${this.id}`);
1490
1511
  if (this._checkForPlugins && !this.info?.plugins?.find?.((v) => v.name === "lavasrc-plugin"))
@@ -1605,7 +1626,8 @@ var LavalinkNode = class _LavalinkNode {
1605
1626
  "Client-Name": String(this._LManager.options.client.username || "Lavalink-Client").replace(
1606
1627
  /[^\x20-\x7E]/g,
1607
1628
  ""
1608
- )
1629
+ ),
1630
+ ...this.NodeManager.LavalinkManager.options?.httpHeaders
1609
1631
  };
1610
1632
  if (typeof this.options.sessionId === "string" || typeof sessionId === "string") {
1611
1633
  headers["Session-Id"] = this.options.sessionId || sessionId;
@@ -1910,7 +1932,10 @@ var LavalinkNode = class _LavalinkNode {
1910
1932
  throw new RangeError(
1911
1933
  `there is no lyrics source (via lavasrc-plugin / java-lyrics-plugin) available in the lavalink node (required for lyrics): ${this.id}`
1912
1934
  );
1913
- const url = `/lyrics?track=${track.encoded}&skipTrackSource=${skipTrackSource}`;
1935
+ let url = `/lyrics?track=${track.encoded}&skipTrackSource=${skipTrackSource}`;
1936
+ if (this.nodeType === "NodeLink" /* NodeLink */) {
1937
+ url = `/loadlyrics?encodedTrack=${track.encoded}`;
1938
+ }
1914
1939
  return await this.request(url);
1915
1940
  },
1916
1941
  /**
@@ -1936,7 +1961,10 @@ var LavalinkNode = class _LavalinkNode {
1936
1961
  throw new RangeError(
1937
1962
  `there is no lyrics source (via lavasrc-plugin / java-lyrics-plugin) available in the lavalink node (required for lyrics): ${this.id}`
1938
1963
  );
1939
- const url = `/sessions/${this.sessionId}/players/${guildId}/track/lyrics?skipTrackSource=${skipTrackSource}`;
1964
+ let url = `/sessions/${this.sessionId}/players/${guildId}/track/lyrics?skipTrackSource=${skipTrackSource}`;
1965
+ if (this.nodeType === "NodeLink" /* NodeLink */) {
1966
+ url = `/loadlyrics?encodedTrack=${this._LManager.getPlayer(guildId)?.queue.current?.encoded}`;
1967
+ }
1940
1968
  return await this.request(url);
1941
1969
  },
1942
1970
  /**
@@ -3069,9 +3097,134 @@ var LavalinkNode = class _LavalinkNode {
3069
3097
  this._LManager.emit("LyricsNotFound", player, track, payload);
3070
3098
  return;
3071
3099
  }
3100
+ /**
3101
+ * @private
3102
+ * util function to check if a provided source is valid with current node.
3103
+ * @param {LavalinkSearchPlatform} src
3104
+ * @returns {boolean} True if provided source is valid.
3105
+ */
3106
+ isLavaSrcSource(src) {
3107
+ const source = /* @__PURE__ */ new Set([]);
3108
+ if (this.info?.sourceManagers.includes("spotify")) source.add("spsearch").add("sprec");
3109
+ if (this.info?.sourceManagers.includes("applemusic")) source.add("amsearch");
3110
+ if (this.info?.sourceManagers.includes("deezer")) source.add("dzsearch").add("dzrec").add("dzisrc");
3111
+ if (this.info?.sourceManagers.includes("yandexmusic")) source.add("ymsearch").add("ymrec");
3112
+ if (this.info?.sourceManagers.includes("vkmusic")) source.add("vksearch").add("vkrec");
3113
+ if (this.info?.sourceManagers.includes("tidal")) source.add("tdsearch").add("tdrec");
3114
+ if (this.info?.sourceManagers.includes("qobuz")) source.add("qbsearch").add("qbisrc").add("qbrec");
3115
+ if (this.info?.sourceManagers.includes("youtube")) source.add("ytsearch").add("ytmsearch");
3116
+ return typeof src === "string" && source.has(src);
3117
+ }
3072
3118
  };
3073
3119
 
3074
3120
  // src/structures/NodeLink.ts
3121
+ var NodeLinkDefaultSources = {
3122
+ // youtubemusic
3123
+ "youtube music": "ytmsearch",
3124
+ youtubemusic: "ytmsearch",
3125
+ ytmsearch: "ytmsearch",
3126
+ ytm: "ytmsearch",
3127
+ musicyoutube: "ytmsearch",
3128
+ "music youtube": "ytmsearch",
3129
+ // youtube
3130
+ youtube: "ytsearch",
3131
+ yt: "ytsearch",
3132
+ ytsearch: "ytsearch",
3133
+ // soundcloud
3134
+ soundcloud: "scsearch",
3135
+ scsearch: "scsearch",
3136
+ sc: "scsearch",
3137
+ // apple music
3138
+ "apple music": "amsearch",
3139
+ apple: "amsearch",
3140
+ applemusic: "amsearch",
3141
+ amsearch: "amsearch",
3142
+ am: "amsearch",
3143
+ musicapple: "amsearch",
3144
+ "music apple": "amsearch",
3145
+ // spotify
3146
+ spotify: "spsearch",
3147
+ spsearch: "spsearch",
3148
+ sp: "spsearch",
3149
+ "spotify.com": "spsearch",
3150
+ spotifycom: "spsearch",
3151
+ sprec: "sprec",
3152
+ spsuggestion: "sprec",
3153
+ // deezer
3154
+ deezer: "dzsearch",
3155
+ dz: "dzsearch",
3156
+ dzsearch: "dzsearch",
3157
+ dzisrc: "dzsearch",
3158
+ // NodeLink doesn't expose `dzisrc` as a prefix string
3159
+ dzrec: "dzrec",
3160
+ // yandexmusic
3161
+ "yandex music": "ymsearch",
3162
+ yandexmusic: "ymsearch",
3163
+ yandex: "ymsearch",
3164
+ ymsearch: "ymsearch",
3165
+ ymrec: "ymsearch",
3166
+ // VK Music
3167
+ vksearch: "vksearch",
3168
+ vkmusic: "vksearch",
3169
+ "vk music": "vksearch",
3170
+ vkrec: "vkrec",
3171
+ vk: "vksearch",
3172
+ // Qobuz
3173
+ qbsearch: "qbsearch",
3174
+ qobuz: "qbsearch",
3175
+ qbisrc: "qbsearch",
3176
+ // NodeLink doesn't expose `qbisrc` as a prefix string
3177
+ qbrec: "qbsearch",
3178
+ // NodeLink doesn't expose `qbrec` as a prefix string
3179
+ // pandora
3180
+ pandora: "pdsearch",
3181
+ pd: "pdsearch",
3182
+ pdsearch: "pdsearch",
3183
+ "pandora music": "pdsearch",
3184
+ pandoramusic: "pdsearch",
3185
+ // speak PLUGIN
3186
+ speak: "speak",
3187
+ // Map Lavalink's `tts` prefix to NodeLink's `gtts`
3188
+ tts: "gtts",
3189
+ ftts: "ftts",
3190
+ flowery: "flowery",
3191
+ "flowery.tts": "flowery",
3192
+ flowerytts: "flowery",
3193
+ // Client sided search platforms
3194
+ bandcamp: "bcsearch",
3195
+ bc: "bcsearch",
3196
+ bcsearch: "bcsearch",
3197
+ // other searches (not supported explicitly in NodeLink prefixes)
3198
+ phsearch: "search",
3199
+ pornhub: "search",
3200
+ porn: "search",
3201
+ // local files
3202
+ local: "local",
3203
+ // http requests
3204
+ http: "http",
3205
+ https: "https",
3206
+ link: "link",
3207
+ uri: "uri",
3208
+ // tidal
3209
+ tidal: "tdsearch",
3210
+ td: "tdsearch",
3211
+ "tidal music": "tdsearch",
3212
+ tdsearch: "tdsearch",
3213
+ tdrec: "tdrec",
3214
+ // jiosaavn
3215
+ jiosaavn: "jssearch",
3216
+ js: "jssearch",
3217
+ jssearch: "jssearch",
3218
+ jsrec: "jsrec",
3219
+ amzsearch: "amsearch",
3220
+ // amazon music (falls back to Apple Music search on NodeLink)
3221
+ // audiomack
3222
+ admsearch: "admsearch",
3223
+ // gaana
3224
+ gnsearch: "gaanasearch",
3225
+ // shazam
3226
+ szsearch: "szsearch"
3227
+ };
3075
3228
  var NodeLinkNode = class extends LavalinkNode {
3076
3229
  nodeType = "NodeLink" /* NodeLink */;
3077
3230
  constructor(options, manager) {
@@ -6027,7 +6180,7 @@ var Player = class {
6027
6180
  );
6028
6181
  if (this.queue.current || this.queue.tracks.length) {
6029
6182
  const trackSources = new Set(
6030
- [this.queue.current, ...this.queue.tracks].map((track) => track.info.sourceName)
6183
+ [this.queue.current, ...this.queue.tracks].map((track) => track?.info?.sourceName).filter(Boolean)
6031
6184
  );
6032
6185
  const missingSources = [...trackSources].filter(
6033
6186
  (source) => !updateNode.info?.sourceManagers.includes(source)
@@ -6274,6 +6427,7 @@ var LavalinkManager = class _LavalinkManager extends EventEmitter2 {
6274
6427
  queueChangesWatcher: options?.queueOptions?.queueChangesWatcher ?? null,
6275
6428
  queueStore: options?.queueOptions?.queueStore ?? new DefaultQueueStore()
6276
6429
  },
6430
+ httpHeaders: options?.httpHeaders ?? {},
6277
6431
  advancedOptions: {
6278
6432
  enableDebugEvents: options?.advancedOptions?.enableDebugEvents ?? false,
6279
6433
  maxFilterFixDuration: options?.advancedOptions?.maxFilterFixDuration ?? 6e5,
@@ -6327,6 +6481,19 @@ var LavalinkManager = class _LavalinkManager extends EventEmitter2 {
6327
6481
  }
6328
6482
  if (typeof options?.queueOptions?.maxPreviousTracks !== "number" || options?.queueOptions?.maxPreviousTracks < 0)
6329
6483
  options.queueOptions.maxPreviousTracks = 25;
6484
+ if (options?.httpHeaders) {
6485
+ if (typeof options.httpHeaders !== "object" || Array.isArray(options.httpHeaders))
6486
+ throw new SyntaxError("ManagerOption.httpHeaders must be an object with string keys and string values");
6487
+ const forbiddenHeaders = ["authorization", "user-id", "client-name", "session-id"];
6488
+ for (const header in options.httpHeaders) {
6489
+ if (forbiddenHeaders.includes(header.toLowerCase()))
6490
+ throw new SyntaxError(
6491
+ `ManagerOption.httpHeaders cannot have the following headers: ${forbiddenHeaders.join(", ")}`
6492
+ );
6493
+ if (typeof options.httpHeaders[header] !== "string")
6494
+ throw new SyntaxError(`ManagerOption.httpHeaders values must be of type string :: ${header}`);
6495
+ }
6496
+ }
6330
6497
  }
6331
6498
  /**
6332
6499
  * Emits a debug event to the LavalinkManager
@@ -6810,6 +6977,7 @@ export {
6810
6977
  LavalinkPlugins,
6811
6978
  ManagerUtils,
6812
6979
  MiniMap,
6980
+ NodeLinkDefaultSources,
6813
6981
  NodeLinkExclusiveEvents,
6814
6982
  NodeLinkNode,
6815
6983
  NodeManager,