magmastream 2.9.3-dev.5 → 2.9.3-dev.7

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.d.ts CHANGED
@@ -3466,11 +3466,22 @@ declare abstract class TrackUtils {
3466
3466
  static setTrackPartial(partial: TrackPartial[]): void;
3467
3467
  /**
3468
3468
  * Checks if the provided argument is a valid Track.
3469
- * If provided an array then every element will be checked.
3470
- * @param trackOrTracks The Track or array of Tracks to check.
3469
+ * @param value The value to check.
3471
3470
  * @returns {boolean} Whether the provided argument is a valid Track.
3472
3471
  */
3473
- static validate(trackOrTracks: unknown): boolean;
3472
+ static isTrack(track: unknown): track is Track;
3473
+ /**
3474
+ * Checks if the provided argument is a valid Track array.
3475
+ * @param value The value to check.
3476
+ * @returns {boolean} Whether the provided argument is a valid Track array.
3477
+ */
3478
+ static isTrackArray(value: unknown): value is Track[];
3479
+ /**
3480
+ * Checks if the provided argument is a valid Track or Track array.
3481
+ * @param value The value to check.
3482
+ * @returns {boolean} Whether the provided argument is a valid Track or Track array.
3483
+ */
3484
+ static validate(value: unknown): value is Track | Track[];
3474
3485
  /**
3475
3486
  * Builds a Track from the raw data from Lavalink and a optional requester.
3476
3487
  * @param data The raw data from Lavalink to build the Track from.
@@ -806,11 +806,8 @@ class Player {
806
806
  if (currentPlayingTrack) {
807
807
  await this.queue.add(currentPlayingTrack, 0);
808
808
  }
809
- await this.play(lastTrack);
810
- }
811
- else {
812
- await this.play(lastTrack);
813
809
  }
810
+ await this.play(lastTrack);
814
811
  this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this, {
815
812
  changeType: Enums_1.PlayerStateEventTypes.TrackChange,
816
813
  details: {
@@ -104,35 +104,55 @@ class Rest {
104
104
  },
105
105
  data: body,
106
106
  timeout: this.node.options.apiRequestTimeoutMs,
107
+ validateStatus: () => true,
107
108
  };
109
+ let response;
108
110
  try {
109
- const response = await (0, axios_1.default)(config);
110
- return response.data;
111
+ response = await (0, axios_1.default)(config);
111
112
  }
112
113
  catch (err) {
113
- const error = err;
114
- if (!error.response) {
115
- throw new MagmastreamError_1.MagmaStreamError({
116
- code: Enums_1.MagmaStreamErrorCode.REST_REQUEST_FAILED,
117
- message: `No response from node ${this.node.options.identifier}: ${error.message}`,
118
- });
119
- }
120
- const data = error.response.data;
121
- if (data?.message === "Guild not found") {
122
- return [];
123
- }
124
- if (error.response.status === 401) {
125
- throw new MagmastreamError_1.MagmaStreamError({
126
- code: Enums_1.MagmaStreamErrorCode.REST_UNAUTHORIZED,
127
- message: `Unauthorized access to node ${this.node.options.identifier}`,
128
- });
129
- }
130
- const dataMessage = typeof data === "string" ? data : data?.message ? data.message : Utils_1.JSONUtils.safe(data, 2);
114
+ const message = err instanceof Error ? err.message : "Unknown error";
131
115
  throw new MagmastreamError_1.MagmaStreamError({
132
116
  code: Enums_1.MagmaStreamErrorCode.REST_REQUEST_FAILED,
133
- message: `Request to node ${this.node.options.identifier} failed with status ${error.response.status}: ${dataMessage}`,
117
+ message: `No response from node ${this.node.options.identifier}: ${message}`,
134
118
  });
135
119
  }
120
+ const { status, data } = response;
121
+ if (status >= 200 && status < 300) {
122
+ return data;
123
+ }
124
+ // Lavalink sometimes returns "Guild not found" for inactive players
125
+ if (status === 404 && data?.message === "Guild not found") {
126
+ return [];
127
+ }
128
+ if (status === 401) {
129
+ throw new MagmastreamError_1.MagmaStreamError({
130
+ code: Enums_1.MagmaStreamErrorCode.REST_UNAUTHORIZED,
131
+ message: `Unauthorized access to node ${this.node.options.identifier}`,
132
+ });
133
+ }
134
+ if (status >= 400 && status < 500) {
135
+ const message = typeof data === "string"
136
+ ? data
137
+ : typeof data === "object" && data !== null && "message" in data && typeof data.message === "string"
138
+ ? data.message
139
+ : "Unknown client error";
140
+ return {
141
+ status,
142
+ error: true,
143
+ message,
144
+ data,
145
+ };
146
+ }
147
+ const safeMessage = typeof data === "string"
148
+ ? data
149
+ : typeof data === "object" && data !== null && "message" in data && typeof data.message === "string"
150
+ ? data.message
151
+ : Utils_1.JSONUtils.safe(data, 2);
152
+ throw new MagmastreamError_1.MagmaStreamError({
153
+ code: Enums_1.MagmaStreamErrorCode.REST_REQUEST_FAILED,
154
+ message: `Request to node ${this.node.options.identifier} failed (${status}): ${safeMessage}`,
155
+ });
136
156
  }
137
157
  /**
138
158
  * Sends a GET request to the specified endpoint and returns the response data.
@@ -9,9 +9,11 @@ const Enums_1 = require("./Enums");
9
9
  const path_1 = tslib_1.__importDefault(require("path"));
10
10
  const safe_stable_stringify_1 = tslib_1.__importDefault(require("safe-stable-stringify"));
11
11
  const MagmastreamError_1 = require("./MagmastreamError");
12
+ const lodash_1 = require("lodash");
12
13
  // import playwright from "playwright";
13
14
  /** @hidden */
14
15
  const SIZES = ["0", "1", "2", "3", "default", "mqdefault", "hqdefault", "maxresdefault"];
16
+ const REQUIRED_TRACK_KEYS = ["track", "title", "uri"];
15
17
  class TrackUtils {
16
18
  static trackPartial = null;
17
19
  static manager;
@@ -54,25 +56,30 @@ class TrackUtils {
54
56
  }
55
57
  /**
56
58
  * Checks if the provided argument is a valid Track.
57
- * If provided an array then every element will be checked.
58
- * @param trackOrTracks The Track or array of Tracks to check.
59
+ * @param value The value to check.
59
60
  * @returns {boolean} Whether the provided argument is a valid Track.
60
61
  */
61
- static validate(trackOrTracks) {
62
- if (typeof trackOrTracks !== "object" || trackOrTracks === null) {
62
+ static isTrack(track) {
63
+ if (typeof track !== "object" || track === null)
63
64
  return false;
64
- }
65
- const isValidTrack = (track) => {
66
- if (typeof track !== "object" || track === null) {
67
- return false;
68
- }
69
- const t = track;
70
- return (typeof t.track === "string" && typeof t.title === "string" && typeof t.identifier === "string" && typeof t.isrc === "string" && typeof t.uri === "string");
71
- };
72
- if (Array.isArray(trackOrTracks)) {
73
- return trackOrTracks.every(isValidTrack);
74
- }
75
- return isValidTrack(trackOrTracks);
65
+ const t = track;
66
+ return REQUIRED_TRACK_KEYS.every((key) => typeof t[key] === "string");
67
+ }
68
+ /**
69
+ * Checks if the provided argument is a valid Track array.
70
+ * @param value The value to check.
71
+ * @returns {boolean} Whether the provided argument is a valid Track array.
72
+ */
73
+ static isTrackArray(value) {
74
+ return Array.isArray(value) && value.every(this.isTrack);
75
+ }
76
+ /**
77
+ * Checks if the provided argument is a valid Track or Track array.
78
+ * @param value The value to check.
79
+ * @returns {boolean} Whether the provided argument is a valid Track or Track array.
80
+ */
81
+ static validate(value) {
82
+ return this.isTrack(value) || this.isTrackArray(value);
76
83
  }
77
84
  /**
78
85
  * Builds a Track from the raw data from Lavalink and a optional requester.
@@ -617,65 +624,87 @@ class PlayerUtils {
617
624
  * @returns The serialized Player instance
618
625
  */
619
626
  static async serializePlayer(player) {
620
- try {
621
- const current = await player.queue.getCurrent();
622
- const tracks = await player.queue.getTracks();
623
- const previous = await player.queue.getPrevious();
624
- const serializeTrack = (track) => ({
625
- ...track,
626
- requester: track.requester ? { id: track.requester.id, username: track.requester.username } : null,
627
- });
628
- const safeNode = player.node
629
- ? JSON.parse(JSON.stringify(player.node, (key, value) => {
630
- if (key === "rest" || key === "players" || key === "shards" || key === "manager")
631
- return undefined;
632
- return value;
633
- }))
634
- : null;
635
- return JSON.parse(JSON.stringify(player, (key, value) => {
636
- if (key === "manager")
637
- return null;
638
- if (key === "node")
639
- return safeNode;
640
- if (key === "filters") {
641
- return {
642
- distortion: value?.distortion ?? null,
643
- equalizer: value?.equalizer ?? [],
644
- karaoke: value?.karaoke ?? null,
645
- rotation: value?.rotation ?? null,
646
- timescale: value?.timescale ?? null,
647
- vibrato: value?.vibrato ?? null,
648
- reverb: value?.reverb ?? null,
649
- volume: value?.volume ?? 1.0,
650
- bassBoostlevel: value?.bassBoostlevel ?? null,
651
- filterStatus: value?.filtersStatus ? { ...value.filtersStatus } : {},
652
- };
653
- }
654
- if (key === "queue") {
655
- return {
656
- current: current ? serializeTrack(current) : null,
657
- tracks: tracks.map(serializeTrack),
658
- previous: previous.map(serializeTrack),
659
- };
660
- }
661
- if (key === "data") {
662
- return {
663
- clientUser: value?.Internal_AutoplayUser ?? null,
664
- nowPlayingMessage: value?.nowPlayingMessage ?? null,
665
- };
666
- }
627
+ const current = await player.queue.getCurrent();
628
+ const tracks = await player.queue.getTracks();
629
+ const previous = await player.queue.getPrevious();
630
+ const serializeTrack = (track) => ({
631
+ ...track,
632
+ requester: track.requester ? { id: track.requester.id, username: track.requester.username } : null,
633
+ });
634
+ const safeNode = player.node
635
+ ? JSON.parse(JSON.stringify(player.node, (key, value) => {
636
+ if (key === "rest" || key === "players" || key === "shards" || key === "manager")
637
+ return undefined;
667
638
  return value;
668
- }));
639
+ }))
640
+ : null;
641
+ const isNonSerializable = (value) => {
642
+ if (typeof value === "function" || typeof value === "symbol")
643
+ return true;
644
+ if (typeof value === "object" && value !== null) {
645
+ const ctorName = value.constructor?.name ?? "";
646
+ return (value instanceof Map ||
647
+ value instanceof Set ||
648
+ value instanceof WeakMap ||
649
+ value instanceof WeakSet ||
650
+ ctorName === "Timeout" ||
651
+ ctorName === "Socket" ||
652
+ ctorName === "TLSSocket" ||
653
+ ctorName === "EventEmitter");
654
+ }
655
+ return false;
656
+ };
657
+ const safeReplacer = (key, value) => {
658
+ if (isNonSerializable(value))
659
+ return undefined;
660
+ if (key === "manager")
661
+ return null;
662
+ if (key === "node")
663
+ return safeNode;
664
+ if (key === "filters" && (0, lodash_1.isPlainObject)(value)) {
665
+ return {
666
+ distortion: value["distortion"] ?? null,
667
+ equalizer: value["equalizer"] ?? [],
668
+ karaoke: value["karaoke"] ?? null,
669
+ rotation: value["rotation"] ?? null,
670
+ timescale: value["timescale"] ?? null,
671
+ vibrato: value["vibrato"] ?? null,
672
+ reverb: value["reverb"] ?? null,
673
+ volume: value["volume"] ?? 1.0,
674
+ bassBoostlevel: value["bassBoostlevel"] ?? null,
675
+ filterStatus: (0, lodash_1.isPlainObject)(value["filtersStatus"]) ? { ...value["filtersStatus"] } : {},
676
+ };
677
+ }
678
+ if (key === "queue") {
679
+ return {
680
+ current: current ? serializeTrack(current) : null,
681
+ tracks: tracks.map(serializeTrack),
682
+ previous: previous.map(serializeTrack),
683
+ };
684
+ }
685
+ if (key === "data" && (0, lodash_1.isPlainObject)(value)) {
686
+ return {
687
+ clientUser: value["Internal_AutoplayUser"] ?? null,
688
+ nowPlayingMessage: value["nowPlayingMessage"] ?? null,
689
+ };
690
+ }
691
+ return value;
692
+ };
693
+ let serialized;
694
+ try {
695
+ serialized = JSON.stringify(player, safeReplacer);
669
696
  }
670
697
  catch (err) {
671
- throw err instanceof MagmastreamError_1.MagmaStreamError
698
+ const error = err instanceof MagmastreamError_1.MagmaStreamError
672
699
  ? err
673
700
  : new MagmastreamError_1.MagmaStreamError({
674
701
  code: Enums_1.MagmaStreamErrorCode.MANAGER_SEARCH_FAILED,
675
702
  message: `An error occurred while searching: ${err instanceof Error ? err.message : String(err)}`,
676
703
  cause: err instanceof Error ? err : undefined,
677
704
  });
705
+ console.error(error);
678
706
  }
707
+ return JSON.parse(serialized);
679
708
  }
680
709
  /**
681
710
  * Gets the base directory for player data.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magmastream",
3
- "version": "2.9.3-dev.5",
3
+ "version": "2.9.3-dev.7",
4
4
  "description": "A user-friendly Lavalink client designed for NodeJS.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",