lavalink-client 2.9.11 → 2.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.
package/dist/index.mjs CHANGED
@@ -339,9 +339,6 @@ var NodeLinkExclusiveEvents = [
339
339
  "LyricsNotFoundEvent"
340
340
  ];
341
341
 
342
- // src/structures/NodeManager.ts
343
- import { EventEmitter } from "events";
344
-
345
342
  // src/structures/Node.ts
346
343
  import { isAbsolute } from "path";
347
344
  import WebSocket from "ws";
@@ -354,6 +351,11 @@ var ReconnectionState = /* @__PURE__ */ ((ReconnectionState2) => {
354
351
  ReconnectionState2["DESTROYING"] = "DESTROYING";
355
352
  return ReconnectionState2;
356
353
  })(ReconnectionState || {});
354
+ var NodeType = /* @__PURE__ */ ((NodeType2) => {
355
+ NodeType2["Lavalink"] = "Lavalink";
356
+ NodeType2["NodeLink"] = "NodeLink";
357
+ return NodeType2;
358
+ })(NodeType || {});
357
359
 
358
360
  // src/structures/Utils.ts
359
361
  import { URL as URL2 } from "url";
@@ -525,12 +527,14 @@ var QueueSymbol = /* @__PURE__ */ Symbol("LC-Queue");
525
527
  var NodeSymbol = /* @__PURE__ */ Symbol("LC-Node");
526
528
  var escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
527
529
  function parseLavalinkConnUrl(connectionUrl) {
528
- if (!connectionUrl.startsWith("lavalink://") && !connectionUrl.startsWith("nodelink://"))
530
+ if (!connectionUrl) throw new Error("ConnectionUrl is required");
531
+ const lowered = connectionUrl.toLowerCase();
532
+ if (!lowered.startsWith("lavalink://") && !lowered.startsWith("nodelink://"))
529
533
  throw new Error(`ConnectionUrl (${connectionUrl}) must start with 'lavalink://' or 'nodelink://'`);
530
534
  const parsed = new URL2(connectionUrl);
531
535
  return {
532
536
  authorization: parsed.password,
533
- nodeType: connectionUrl.startsWith("lavalink://") ? "Lavalink" : "NodeLink",
537
+ nodeType: lowered.startsWith("lavalink://") ? "Lavalink" /* Lavalink */ : "NodeLink" /* NodeLink */,
534
538
  id: parsed.username,
535
539
  host: parsed.hostname,
536
540
  port: Number(parsed.port)
@@ -1184,7 +1188,7 @@ var LavalinkNode = class _LavalinkNode {
1184
1188
  heartBeatPongTimestamp = 0;
1185
1189
  heartBeatInterval;
1186
1190
  pingTimeout;
1187
- nodeType = "Lavalink";
1191
+ nodeType = "Lavalink" /* Lavalink */;
1188
1192
  isAlive = false;
1189
1193
  static _NodeLinkClass = null;
1190
1194
  /** The provided Options of the Node */
@@ -1258,7 +1262,7 @@ var LavalinkNode = class _LavalinkNode {
1258
1262
  * Returns wether the plugin validations are enabled or not
1259
1263
  */
1260
1264
  get _checkForPlugins() {
1261
- if (this.nodeType === "NodeLink") return false;
1265
+ if (this.nodeType === "NodeLink" /* NodeLink */) return false;
1262
1266
  return !!this.options?.autoChecks?.pluginValidations;
1263
1267
  }
1264
1268
  /**
@@ -1328,16 +1332,17 @@ var LavalinkNode = class _LavalinkNode {
1328
1332
  heartBeatInterval: 3e4,
1329
1333
  enablePingOnStatsCheck: true,
1330
1334
  closeOnError: true,
1335
+ nodeType: "Lavalink" /* Lavalink */,
1331
1336
  ...options,
1332
1337
  autoChecks: {
1333
1338
  sourcesValidations: options?.autoChecks?.sourcesValidations ?? true,
1334
1339
  pluginValidations: options?.autoChecks?.pluginValidations ?? true
1335
1340
  }
1336
1341
  };
1337
- if (this.options.nodeType === "NodeLink" && this.constructor.name === "LavalinkNode" && _LavalinkNode._NodeLinkClass) {
1342
+ if (this.options.nodeType === "NodeLink" /* NodeLink */ && this.constructor.name === "LavalinkNode" && _LavalinkNode._NodeLinkClass) {
1338
1343
  return new _LavalinkNode._NodeLinkClass(options, manager);
1339
1344
  }
1340
- this.nodeType = this.options.nodeType || "Lavalink";
1345
+ this.nodeType = this.options.nodeType;
1341
1346
  this.NodeManager = manager;
1342
1347
  this.validate();
1343
1348
  if (this.options.secure && this.options.port !== 443)
@@ -2280,20 +2285,22 @@ var LavalinkNode = class _LavalinkNode {
2280
2285
  throw new SyntaxError("LavalinkNode.autoChecks.pluginValidations must be either false | true aka boolean");
2281
2286
  if (this.options.regions !== void 0 && (!Array.isArray(this.options.regions) || !this.options.regions.every((r) => typeof r === "string")))
2282
2287
  throw new SyntaxError("LavalinkNode.regions must be an Array of strings");
2288
+ if (this.options.nodeType && !NodeType[this.options.nodeType])
2289
+ throw new SyntaxError("LavalinkNode.nodeType must be a valid NodeType enum value");
2283
2290
  }
2284
2291
  /**
2285
2292
  * Checks if the node is a NodeLink node
2286
2293
  * @returns true if the node is a NodeLink node
2287
2294
  */
2288
2295
  isNodeLink() {
2289
- return this.nodeType === "NodeLink";
2296
+ return this.nodeType === "NodeLink" /* NodeLink */;
2290
2297
  }
2291
2298
  /**
2292
2299
  * Checks if the node is a Lavalink node
2293
2300
  * @returns true if the node is a Lavalink node
2294
2301
  */
2295
2302
  isLavalinkNode() {
2296
- return this.nodeType === "Lavalink";
2303
+ return this.nodeType === "Lavalink" /* Lavalink */;
2297
2304
  }
2298
2305
  /**
2299
2306
  * Sync the data of the player you make an action to lavalink to
@@ -3066,13 +3073,13 @@ var LavalinkNode = class _LavalinkNode {
3066
3073
 
3067
3074
  // src/structures/NodeLink.ts
3068
3075
  var NodeLinkNode = class extends LavalinkNode {
3069
- nodeType = "NodeLink";
3076
+ nodeType = "NodeLink" /* NodeLink */;
3070
3077
  constructor(options, manager) {
3071
3078
  super(options, manager);
3072
- if (this.options.nodeType === "Lavalink" && this.constructor.name === "NodeLink") {
3079
+ if (this.options.nodeType === "Lavalink" /* Lavalink */ && (this.constructor.name === "NodeLinkNode" || this.constructor.name === "NodeLink")) {
3073
3080
  return new LavalinkNode(options, manager);
3074
3081
  }
3075
- this.nodeType = "NodeLink";
3082
+ this.nodeType = "NodeLink" /* NodeLink */;
3076
3083
  }
3077
3084
  /**
3078
3085
  * Uses the gapless feature to set the next track to be played.
@@ -3413,6 +3420,7 @@ var NodeLinkNode = class extends LavalinkNode {
3413
3420
  LavalinkNode._NodeLinkClass = NodeLinkNode;
3414
3421
 
3415
3422
  // src/structures/NodeManager.ts
3423
+ import { EventEmitter } from "events";
3416
3424
  var NodeManager = class extends EventEmitter {
3417
3425
  /**
3418
3426
  * Emit an event
@@ -3474,9 +3482,7 @@ var NodeManager = class extends EventEmitter {
3474
3482
  super();
3475
3483
  this.LavalinkManager = LavalinkManager2;
3476
3484
  if (this.LavalinkManager.options.nodes)
3477
- this.LavalinkManager.options.nodes.forEach((node) => {
3478
- this.createNode(node);
3479
- });
3485
+ this.LavalinkManager.options.nodes.forEach((node) => this.createNode(node));
3480
3486
  }
3481
3487
  /**
3482
3488
  * Disconnects all Nodes from lavalink ws sockets
@@ -3537,9 +3543,21 @@ var NodeManager = class extends EventEmitter {
3537
3543
  * @returns The node that was created
3538
3544
  */
3539
3545
  createNode(options) {
3546
+ if (options instanceof NodeLinkNode) {
3547
+ const preExistingNode = this.nodes.get(options.id);
3548
+ if (preExistingNode) return preExistingNode;
3549
+ this.nodes.set(options.id, options);
3550
+ return options;
3551
+ }
3552
+ if (options instanceof LavalinkNode) {
3553
+ const preExistingNode = this.nodes.get(options.id);
3554
+ if (preExistingNode) return preExistingNode;
3555
+ this.nodes.set(options.id, options);
3556
+ return options;
3557
+ }
3540
3558
  if (this.nodes.has(options.id || `${options.host}:${options.port}`))
3541
3559
  return this.nodes.get(options.id || `${options.host}:${options.port}`);
3542
- const newNode = options.nodeType === "NodeLink" ? new NodeLinkNode(options, this) : new LavalinkNode(options, this);
3560
+ const newNode = options.nodeType === "NodeLink" /* NodeLink */ ? new NodeLinkNode(options, this) : new LavalinkNode(options, this);
3543
3561
  this.nodes.set(newNode.id, newNode);
3544
3562
  return newNode;
3545
3563
  }
@@ -3548,48 +3566,57 @@ var NodeManager = class extends EventEmitter {
3548
3566
  * @param sortType The type of sorting to use
3549
3567
  * @returns
3550
3568
  */
3551
- leastUsedNodes(sortType = "players") {
3569
+ leastUsedNodes(sortType = "players", filterForNodeTypes) {
3570
+ const normalizedFilterForNodeTypes = filterForNodeTypes?.length ? filterForNodeTypes : ["Lavalink" /* Lavalink */, "NodeLink" /* NodeLink */];
3552
3571
  const connectedNodes = Array.from(this.nodes.values()).filter((node) => node.connected);
3572
+ const normalizedNodeTypes = new Set(
3573
+ normalizedFilterForNodeTypes.map(
3574
+ (nodeTypeFilter) => Object.values(NodeType).includes(nodeTypeFilter) ? nodeTypeFilter : nodeTypeFilter.nodeType
3575
+ )
3576
+ );
3577
+ const filteredConnectedNodes = connectedNodes.filter((node) => normalizedNodeTypes.has(node.nodeType));
3553
3578
  switch (sortType) {
3554
3579
  case "memory":
3555
3580
  {
3556
- return connectedNodes.sort((a, b) => (a.stats?.memory?.used || 0) - (b.stats?.memory?.used || 0));
3581
+ return filteredConnectedNodes.sort(
3582
+ (a, b) => (a.stats?.memory?.used || 0) - (b.stats?.memory?.used || 0)
3583
+ );
3557
3584
  }
3558
3585
  break;
3559
3586
  case "cpuLavalink":
3560
3587
  {
3561
- return connectedNodes.sort(
3588
+ return filteredConnectedNodes.sort(
3562
3589
  (a, b) => (a.stats?.cpu?.lavalinkLoad || 0) - (b.stats?.cpu?.lavalinkLoad || 0)
3563
3590
  );
3564
3591
  }
3565
3592
  break;
3566
3593
  case "cpuSystem":
3567
3594
  {
3568
- return connectedNodes.sort(
3595
+ return filteredConnectedNodes.sort(
3569
3596
  (a, b) => (a.stats?.cpu?.systemLoad || 0) - (b.stats?.cpu?.systemLoad || 0)
3570
3597
  );
3571
3598
  }
3572
3599
  break;
3573
3600
  case "calls":
3574
3601
  {
3575
- return connectedNodes.sort((a, b) => a.calls - b.calls);
3602
+ return filteredConnectedNodes.sort((a, b) => a.calls - b.calls);
3576
3603
  }
3577
3604
  break;
3578
3605
  case "playingPlayers":
3579
3606
  {
3580
- return connectedNodes.sort(
3607
+ return filteredConnectedNodes.sort(
3581
3608
  (a, b) => (a.stats?.playingPlayers || 0) - (b.stats?.playingPlayers || 0)
3582
3609
  );
3583
3610
  }
3584
3611
  break;
3585
3612
  case "players":
3586
3613
  {
3587
- return connectedNodes.sort((a, b) => (a.stats?.players || 0) - (b.stats?.players || 0));
3614
+ return filteredConnectedNodes.sort((a, b) => (a.stats?.players || 0) - (b.stats?.players || 0));
3588
3615
  }
3589
3616
  break;
3590
3617
  default:
3591
3618
  {
3592
- return connectedNodes.sort((a, b) => (a.stats?.players || 0) - (b.stats?.players || 0));
3619
+ return filteredConnectedNodes.sort((a, b) => (a.stats?.players || 0) - (b.stats?.players || 0));
3593
3620
  }
3594
3621
  break;
3595
3622
  }
@@ -3622,13 +3649,22 @@ var NodeManager = class extends EventEmitter {
3622
3649
  }
3623
3650
  /**
3624
3651
  * Get a node from the nodeManager
3625
- * @param node The node to get
3652
+ * @param node The node to get either by idetnifier, by class or by enum
3626
3653
  * @returns The node that was retrieved
3627
3654
  */
3628
3655
  getNode(node) {
3656
+ if (!!node && Object.values(NodeType).includes(node)) {
3657
+ return this.leastUsedNodes().filter((node2) => node2.nodeType === node2)[0];
3658
+ }
3659
+ if (!!node && node instanceof NodeLinkNode) {
3660
+ return this.leastUsedNodes().filter((node2) => node2 instanceof NodeLinkNode)[0];
3661
+ }
3662
+ if (!!node && node instanceof LavalinkNode) {
3663
+ return this.leastUsedNodes().filter((node2) => node2 instanceof LavalinkNode)[0];
3664
+ }
3629
3665
  const decodeNode = typeof node === "string" ? this.nodes.get(node) : node;
3630
3666
  if (!decodeNode) return void 0;
3631
- if (decodeNode.nodeType === "NodeLink") return decodeNode;
3667
+ if (decodeNode.nodeType === "NodeLink" /* NodeLink */) return decodeNode;
3632
3668
  return decodeNode;
3633
3669
  }
3634
3670
  };
@@ -6267,9 +6303,11 @@ var LavalinkManager = class _LavalinkManager extends EventEmitter2 {
6267
6303
  throw new SyntaxError("ManagerOption.autoSkipOnResolveError must be either false | true aka boolean");
6268
6304
  if (options?.emitNewSongsOnly && typeof options?.emitNewSongsOnly !== "boolean")
6269
6305
  throw new SyntaxError("ManagerOption.emitNewSongsOnly must be either false | true aka boolean");
6270
- if (!options?.nodes || !Array.isArray(options?.nodes) || !options?.nodes.every((node) => this.utils.isNodeOptions(node)))
6306
+ if (!options?.nodes || !Array.isArray(options?.nodes) || !options?.nodes.every(
6307
+ (node) => node instanceof NodeLinkNode || node instanceof LavalinkNode || this.utils.isNodeOptions(node)
6308
+ ))
6271
6309
  throw new SyntaxError(
6272
- "ManagerOption.nodes must be an Array of NodeOptions and is required of at least 1 Node"
6310
+ "ManagerOption.nodes must be an Array of NodeOptions or the Node-Classes 'NodeLinkNode' or 'LavalinkNode' and is required of at least 1 Node"
6273
6311
  );
6274
6312
  if (options?.queueOptions?.queueStore) {
6275
6313
  const keys = Object.getOwnPropertyNames(Object.getPrototypeOf(options?.queueOptions?.queueStore));
@@ -6325,48 +6363,50 @@ var LavalinkManager = class _LavalinkManager extends EventEmitter2 {
6325
6363
  * port: 2333,
6326
6364
  * id: "testnode"
6327
6365
  * },
6366
+ * // you can also use the util like this, and it will return a valid node option object. must start with: lavalink:// | nodelink://
6367
+ * // parseLavalinkConnUrl("nodelink://<nodeId>:<nodeAuthorization(Password)>@<NodeHost>:<NodePort>")
6328
6368
  * sendToShard(guildId, payload) => client.guilds.cache.get(guildId)?.shard?.send(payload),
6329
- * client: {
6330
- * id: process.env.CLIENT_ID,
6331
- * username: "TESTBOT"
6332
- * },
6333
- * // optional Options:
6334
- * autoSkip: true,
6335
- * playerOptions: {
6336
- * applyVolumeAsFilter: false,
6337
- * clientBasedPositionUpdateInterval: 150,
6338
- * defaultSearchPlatform: "ytmsearch",
6339
- * allowCustomSources: false,
6340
- * volumeDecrementer: 0.75,
6341
- * //requesterTransformer: YourRequesterTransformerFunction,
6342
- * onDisconnect: {
6343
- * autoReconnect: true,
6344
- * destroyPlayer: false
6345
- * },
6346
- * onEmptyQueue: {
6347
- * destroyAfterMs: 30_000,
6348
- * //autoPlayFunction: YourAutoplayFunction,
6349
- * },
6350
- * useUnresolvedData: true
6369
+ * ],
6370
+ * client: {
6371
+ * id: process.env.CLIENT_ID,
6372
+ * username: "TESTBOT"
6373
+ * },
6374
+ * // optional Options:
6375
+ * autoSkip: true,
6376
+ * playerOptions: {
6377
+ * applyVolumeAsFilter: false,
6378
+ * clientBasedPositionUpdateInterval: 150,
6379
+ * defaultSearchPlatform: "ytmsearch",
6380
+ * allowCustomSources: false,
6381
+ * volumeDecrementer: 0.75,
6382
+ * //requesterTransformer: YourRequesterTransformerFunction,
6383
+ * onDisconnect: {
6384
+ * autoReconnect: true,
6385
+ * destroyPlayer: false
6351
6386
  * },
6352
- * queueOptions: {
6353
- * maxPreviousTracks: 25,
6354
- * //queueStore: yourCustomQueueStoreManagerClass,
6355
- * //queueChangesWatcher: yourCustomQueueChangesWatcherClass
6387
+ * onEmptyQueue: {
6388
+ * destroyAfterMs: 30_000,
6389
+ * //autoPlayFunction: YourAutoplayFunction,
6356
6390
  * },
6357
- * linksBlacklist: [],
6358
- * linksWhitelist: [],
6359
- * advancedOptions: {
6360
- * maxFilterFixDuration: 600_000,
6361
- * debugOptions: {
6362
- * noAudio: false,
6363
- * playerDestroy: {
6364
- * dontThrowError: false,
6365
- * debugLogs: false
6366
- * }
6391
+ * useUnresolvedData: true
6392
+ * },
6393
+ * queueOptions: {
6394
+ * maxPreviousTracks: 25,
6395
+ * //queueStore: yourCustomQueueStoreManagerClass,
6396
+ * //queueChangesWatcher: yourCustomQueueChangesWatcherClass
6397
+ * },
6398
+ * linksBlacklist: [],
6399
+ * linksWhitelist: [],
6400
+ * advancedOptions: {
6401
+ * maxFilterFixDuration: 600_000,
6402
+ * debugOptions: {
6403
+ * noAudio: false,
6404
+ * playerDestroy: {
6405
+ * dontThrowError: false,
6406
+ * debugLogs: false
6367
6407
  * }
6368
6408
  * }
6369
- * ]
6409
+ * }
6370
6410
  * })
6371
6411
  * ```
6372
6412
  */
@@ -6774,6 +6814,7 @@ export {
6774
6814
  NodeLinkNode,
6775
6815
  NodeManager,
6776
6816
  NodeSymbol,
6817
+ NodeType,
6777
6818
  Player,
6778
6819
  Queue,
6779
6820
  QueueSaver,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lavalink-client",
3
- "version": "2.9.11",
3
+ "version": "2.10.0",
4
4
  "description": "Easy, flexible and feature-rich lavalink@v4 Client. Both for Beginners and Proficients. - Supports NodeLink@v3 too.",
5
5
  "keywords": [
6
6
  "advanced",