magmastream 2.9.3-dev.23 → 2.9.3-dev.25
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 +6 -0
- package/dist/structures/Manager.js +78 -87
- package/dist/structures/Node.js +4 -2
- package/dist/structures/Utils.js +0 -1
- package/dist/wrappers/discordeno.js +4 -0
- package/package.json +105 -105
package/dist/index.d.ts
CHANGED
|
@@ -915,6 +915,10 @@ interface ManagerOptions {
|
|
|
915
915
|
* @default UseNodeOptions.LeastPlayers
|
|
916
916
|
*/
|
|
917
917
|
useNode?: UseNodeOptions.LeastLoad | UseNodeOptions.LeastPlayers;
|
|
918
|
+
/** Whether the manager should listen to SIGINT and SIGTERM events.
|
|
919
|
+
* @default true
|
|
920
|
+
*/
|
|
921
|
+
listenToSIGEvents?: boolean;
|
|
918
922
|
/**
|
|
919
923
|
* Function to send data to the websocket.
|
|
920
924
|
* @param id The ID of the node to send the data to.
|
|
@@ -3151,6 +3155,7 @@ declare class Manager extends EventEmitter {
|
|
|
3151
3155
|
private get priorityNode();
|
|
3152
3156
|
protected send(packet: GatewayVoiceStateUpdate): unknown;
|
|
3153
3157
|
protected getUserFromCache(id: string): AnyUser | undefined;
|
|
3158
|
+
protected getGuildFromCache(id: string): AnyGuild | undefined;
|
|
3154
3159
|
sendPacket(packet: GatewayVoiceStateUpdate): unknown;
|
|
3155
3160
|
/**
|
|
3156
3161
|
* Resolves a PortableUser or ID to a real user object.
|
|
@@ -3703,6 +3708,7 @@ declare class DiscordenoManager extends Manager {
|
|
|
3703
3708
|
* Uses user-provided cache getter if available, otherwise falls back to minimal info.
|
|
3704
3709
|
*/
|
|
3705
3710
|
resolveUser(user: AnyUser | string): Promise<User$2 | AnyUser>;
|
|
3711
|
+
resolveGuild(guildId: string): AnyGuild;
|
|
3706
3712
|
}
|
|
3707
3713
|
|
|
3708
3714
|
/**
|
|
@@ -95,6 +95,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
95
95
|
deleteDestroyedPlayers: options.stateStorage?.deleteDestroyedPlayers ?? true,
|
|
96
96
|
},
|
|
97
97
|
autoPlaySearchPlatforms: options.autoPlaySearchPlatforms ?? [Enums_1.AutoPlayPlatform.YouTube],
|
|
98
|
+
listenToSIGEvents: options.listenToSIGEvents ?? true,
|
|
98
99
|
send: this._send,
|
|
99
100
|
};
|
|
100
101
|
Utils_1.AutoPlayUtils.init(this);
|
|
@@ -102,49 +103,51 @@ class Manager extends events_1.EventEmitter {
|
|
|
102
103
|
for (const nodeOptions of this.options.nodes)
|
|
103
104
|
new Node_1.Node(this, nodeOptions);
|
|
104
105
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
106
|
+
if (this.options.listenToSIGEvents) {
|
|
107
|
+
process.on("SIGINT", async () => {
|
|
108
|
+
console.warn("\x1b[33mSIGINT received! Graceful shutdown initiated...\x1b[0m");
|
|
109
|
+
try {
|
|
110
|
+
await this.handleShutdown();
|
|
111
|
+
console.warn("\x1b[32mShutdown complete. Waiting for Node.js event loop to empty...\x1b[0m");
|
|
112
|
+
// Prevent forced exit by Windows
|
|
113
|
+
setTimeout(() => {
|
|
114
|
+
process.exit(0);
|
|
115
|
+
}, 2000);
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
119
|
+
? err
|
|
120
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
121
|
+
code: Enums_1.MagmaStreamErrorCode.MANAGER_SHUTDOWN_FAILED,
|
|
122
|
+
message: "An unknown error occurred.",
|
|
123
|
+
cause: err,
|
|
124
|
+
context: { stage: "SIGINT" },
|
|
125
|
+
});
|
|
126
|
+
console.error(error);
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
process.on("SIGTERM", async () => {
|
|
131
|
+
console.warn("\x1b[33mSIGTERM received! Graceful shutdown initiated...\x1b[0m");
|
|
132
|
+
try {
|
|
133
|
+
await this.handleShutdown();
|
|
134
|
+
console.warn("\x1b[32mShutdown complete. Exiting now...\x1b[0m");
|
|
112
135
|
process.exit(0);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
process.on("SIGTERM", async () => {
|
|
129
|
-
console.warn("\x1b[33mSIGTERM received! Graceful shutdown initiated...\x1b[0m");
|
|
130
|
-
try {
|
|
131
|
-
await this.handleShutdown();
|
|
132
|
-
console.warn("\x1b[32mShutdown complete. Exiting now...\x1b[0m");
|
|
133
|
-
process.exit(0);
|
|
134
|
-
}
|
|
135
|
-
catch (err) {
|
|
136
|
-
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
137
|
-
? err
|
|
138
|
-
: new MagmastreamError_1.MagmaStreamError({
|
|
139
|
-
code: Enums_1.MagmaStreamErrorCode.MANAGER_SHUTDOWN_FAILED,
|
|
140
|
-
message: "An unknown error occurred.",
|
|
141
|
-
cause: err,
|
|
142
|
-
context: { stage: "SIGTERM" },
|
|
143
|
-
});
|
|
144
|
-
console.error(error);
|
|
145
|
-
process.exit(1);
|
|
146
|
-
}
|
|
147
|
-
});
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
139
|
+
? err
|
|
140
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
141
|
+
code: Enums_1.MagmaStreamErrorCode.MANAGER_SHUTDOWN_FAILED,
|
|
142
|
+
message: "An unknown error occurred.",
|
|
143
|
+
cause: err,
|
|
144
|
+
context: { stage: "SIGTERM" },
|
|
145
|
+
});
|
|
146
|
+
console.error(error);
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
148
151
|
}
|
|
149
152
|
/**
|
|
150
153
|
* Initiates the Manager.
|
|
@@ -527,10 +530,10 @@ class Manager extends events_1.EventEmitter {
|
|
|
527
530
|
});
|
|
528
531
|
// Read guild directories inside players base dir
|
|
529
532
|
const guildDirs = await promises_1.default.readdir(playersBaseDir, { withFileTypes: true });
|
|
530
|
-
for (const
|
|
531
|
-
if (!
|
|
533
|
+
for (const file of guildDirs) {
|
|
534
|
+
if (!file.isDirectory())
|
|
532
535
|
continue;
|
|
533
|
-
const guildId =
|
|
536
|
+
const guildId = file.name;
|
|
534
537
|
const stateFilePath = Utils_1.PlayerUtils.getPlayerStatePath(guildId);
|
|
535
538
|
try {
|
|
536
539
|
await promises_1.default.access(stateFilePath);
|
|
@@ -541,11 +544,9 @@ class Manager extends events_1.EventEmitter {
|
|
|
541
544
|
const hasGuild = this.resolveGuild(state.guildId);
|
|
542
545
|
if (!hasGuild)
|
|
543
546
|
continue;
|
|
544
|
-
const lavaPlayer = await node.rest.
|
|
545
|
-
if (!lavaPlayer)
|
|
546
|
-
await this.destroy(state.guildId);
|
|
547
|
+
const lavaPlayer = (await node.rest.get(`/v4/sessions/${state.node.sessionId}/players/${state.guildId}`));
|
|
548
|
+
if (!lavaPlayer)
|
|
547
549
|
continue;
|
|
548
|
-
}
|
|
549
550
|
const playerOptions = {
|
|
550
551
|
guildId: state.options.guildId,
|
|
551
552
|
textChannelId: state.options.textChannelId,
|
|
@@ -556,23 +557,8 @@ class Manager extends events_1.EventEmitter {
|
|
|
556
557
|
applyVolumeAsFilter: state.options.applyVolumeAsFilter,
|
|
557
558
|
pauseOnDisconnect: state.options.pauseOnDisconnect,
|
|
558
559
|
};
|
|
559
|
-
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Recreating player: ${state.guildId} from saved file: ${Utils_1.JSONUtils.safe(state.options, 2)}`);
|
|
560
560
|
const player = this.create(playerOptions);
|
|
561
|
-
player.
|
|
562
|
-
await player.node.rest.updatePlayer({
|
|
563
|
-
guildId: state.options.guildId,
|
|
564
|
-
data: {
|
|
565
|
-
voice: {
|
|
566
|
-
token: state.voiceState.event.token,
|
|
567
|
-
endpoint: state.voiceState.event.endpoint,
|
|
568
|
-
sessionId: state.voiceState.sessionId,
|
|
569
|
-
channelId: state.voiceState.channelId,
|
|
570
|
-
},
|
|
571
|
-
},
|
|
572
|
-
});
|
|
573
|
-
const tracks = [];
|
|
574
|
-
const currentTrack = state.queue.current;
|
|
575
|
-
const queueTracks = state.queue.tracks;
|
|
561
|
+
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Recreating player: ${state.guildId} from saved file: ${Utils_1.JSONUtils.safe(state.options, 2)}`);
|
|
576
562
|
if (state.isAutoplay) {
|
|
577
563
|
const savedUser = state.data.clientUser;
|
|
578
564
|
if (savedUser) {
|
|
@@ -584,6 +570,9 @@ class Manager extends events_1.EventEmitter {
|
|
|
584
570
|
if (savedNowPlayingMessage) {
|
|
585
571
|
player.setNowPlayingMessage(savedNowPlayingMessage);
|
|
586
572
|
}
|
|
573
|
+
const tracks = [];
|
|
574
|
+
const currentTrack = state.queue.current;
|
|
575
|
+
const queueTracks = state.queue.tracks;
|
|
587
576
|
if (lavaPlayer.track) {
|
|
588
577
|
await player.queue.clear();
|
|
589
578
|
if (currentTrack) {
|
|
@@ -644,7 +633,6 @@ class Manager extends events_1.EventEmitter {
|
|
|
644
633
|
else {
|
|
645
634
|
await player.queue.clearPrevious();
|
|
646
635
|
}
|
|
647
|
-
await player.pause(state.paused);
|
|
648
636
|
if (state.trackRepeat)
|
|
649
637
|
player.setTrackRepeat(true);
|
|
650
638
|
if (state.queueRepeat)
|
|
@@ -690,6 +678,13 @@ class Manager extends events_1.EventEmitter {
|
|
|
690
678
|
filterActions[filter](true);
|
|
691
679
|
}
|
|
692
680
|
}
|
|
681
|
+
player.connect();
|
|
682
|
+
if (lavaPlayer.track) {
|
|
683
|
+
await player.play(Utils_1.TrackUtils.build(lavaPlayer.track, currentTrack.requester, currentTrack.isAutoplay), {
|
|
684
|
+
startTime: lavaPlayer.state.position ?? 0,
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
await player.pause(state.paused);
|
|
693
688
|
try {
|
|
694
689
|
await promises_1.default.rm(Utils_1.PlayerUtils.getPlayerStatePath(guildId), { force: true });
|
|
695
690
|
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Deleted player state folder for guild ${guildId}`);
|
|
@@ -731,10 +726,9 @@ class Manager extends events_1.EventEmitter {
|
|
|
731
726
|
const hasGuild = this.resolveGuild(guildId);
|
|
732
727
|
if (!hasGuild)
|
|
733
728
|
continue;
|
|
734
|
-
const lavaPlayer = await node.rest.
|
|
735
|
-
if (!lavaPlayer)
|
|
729
|
+
const lavaPlayer = (await node.rest.get(`/v4/sessions/${state.node.sessionId}/players/${state.guildId}`));
|
|
730
|
+
if (!lavaPlayer)
|
|
736
731
|
await this.destroy(guildId);
|
|
737
|
-
}
|
|
738
732
|
const playerOptions = {
|
|
739
733
|
guildId: state.options.guildId,
|
|
740
734
|
textChannelId: state.options.textChannelId,
|
|
@@ -745,24 +739,8 @@ class Manager extends events_1.EventEmitter {
|
|
|
745
739
|
applyVolumeAsFilter: state.options.applyVolumeAsFilter,
|
|
746
740
|
pauseOnDisconnect: state.options.pauseOnDisconnect,
|
|
747
741
|
};
|
|
748
|
-
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Recreating player: ${guildId} from Redis`);
|
|
749
742
|
const player = this.create(playerOptions);
|
|
750
|
-
|
|
751
|
-
await player.node.rest.updatePlayer({
|
|
752
|
-
guildId: state.options.guildId,
|
|
753
|
-
data: {
|
|
754
|
-
voice: {
|
|
755
|
-
token: state.voiceState.event.token,
|
|
756
|
-
endpoint: state.voiceState.event.endpoint,
|
|
757
|
-
sessionId: state.voiceState.sessionId,
|
|
758
|
-
channelId: state.voiceState.channelId,
|
|
759
|
-
},
|
|
760
|
-
},
|
|
761
|
-
});
|
|
762
|
-
// Rest of the player state restoration code (tracks, filters, etc.)
|
|
763
|
-
const tracks = [];
|
|
764
|
-
const currentTrack = state.queue.current;
|
|
765
|
-
const queueTracks = state.queue.tracks;
|
|
743
|
+
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Recreating player: ${guildId} from Redis`);
|
|
766
744
|
if (state.isAutoplay) {
|
|
767
745
|
const savedUser = state.data.clientUser;
|
|
768
746
|
if (savedUser) {
|
|
@@ -774,6 +752,10 @@ class Manager extends events_1.EventEmitter {
|
|
|
774
752
|
if (savedNowPlayingMessage) {
|
|
775
753
|
player.setNowPlayingMessage(savedNowPlayingMessage);
|
|
776
754
|
}
|
|
755
|
+
// Rest of the player state restoration code (tracks, filters, etc.)
|
|
756
|
+
const tracks = [];
|
|
757
|
+
const currentTrack = state.queue.current;
|
|
758
|
+
const queueTracks = state.queue.tracks;
|
|
777
759
|
if (lavaPlayer.track) {
|
|
778
760
|
await player.queue.clear();
|
|
779
761
|
if (currentTrack) {
|
|
@@ -840,7 +822,6 @@ class Manager extends events_1.EventEmitter {
|
|
|
840
822
|
else {
|
|
841
823
|
await player.queue.clearPrevious();
|
|
842
824
|
}
|
|
843
|
-
await player.pause(state.paused);
|
|
844
825
|
if (state.trackRepeat)
|
|
845
826
|
player.setTrackRepeat(true);
|
|
846
827
|
if (state.queueRepeat)
|
|
@@ -887,6 +868,13 @@ class Manager extends events_1.EventEmitter {
|
|
|
887
868
|
filterActions[filter](true);
|
|
888
869
|
}
|
|
889
870
|
}
|
|
871
|
+
player.connect();
|
|
872
|
+
if (lavaPlayer.track) {
|
|
873
|
+
await player.play(Utils_1.TrackUtils.build(lavaPlayer.track, currentTrack.requester, currentTrack.isAutoplay), {
|
|
874
|
+
startTime: lavaPlayer.state.position ?? 0,
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
await player.pause(state.paused);
|
|
890
878
|
// After processing, delete the Redis key
|
|
891
879
|
await this.redis.del(key);
|
|
892
880
|
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Deleted player state from Redis: ${key}`);
|
|
@@ -1352,6 +1340,9 @@ class Manager extends events_1.EventEmitter {
|
|
|
1352
1340
|
getUserFromCache(id) {
|
|
1353
1341
|
return this._getUser?.(id);
|
|
1354
1342
|
}
|
|
1343
|
+
getGuildFromCache(id) {
|
|
1344
|
+
return this._getGuild?.(id);
|
|
1345
|
+
}
|
|
1355
1346
|
sendPacket(packet) {
|
|
1356
1347
|
return this.send(packet);
|
|
1357
1348
|
}
|
package/dist/structures/Node.js
CHANGED
|
@@ -127,7 +127,8 @@ class Node {
|
|
|
127
127
|
}
|
|
128
128
|
getNodeSessionPath() {
|
|
129
129
|
const safeId = String(this.options.identifier).replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
130
|
-
|
|
130
|
+
const clusterId = String(this.manager.options.clusterId ?? 0);
|
|
131
|
+
return path_1.default.join(this.getNodeSessionsDir(), `${safeId}__${clusterId}.txt`);
|
|
131
132
|
}
|
|
132
133
|
/**
|
|
133
134
|
* Loads session IDs from the sessionIds.json file if it exists.
|
|
@@ -486,10 +487,11 @@ class Node {
|
|
|
486
487
|
case "ready":
|
|
487
488
|
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[NODE] Node message: ${Utils_1.JSONUtils.safe(payload, 2)}`);
|
|
488
489
|
this.rest.setSessionId(payload.sessionId);
|
|
490
|
+
const hadPreviousSession = this.sessionId && this.sessionId !== payload.sessionId;
|
|
489
491
|
this.sessionId = payload.sessionId;
|
|
490
492
|
await this.updateSessionId();
|
|
491
493
|
this.info = await this.fetchInfo();
|
|
492
|
-
if (payload.resumed) {
|
|
494
|
+
if (payload.resumed || !hadPreviousSession) {
|
|
493
495
|
await this.manager.loadPlayerStates(this.options.identifier);
|
|
494
496
|
}
|
|
495
497
|
if (this.options.enableSessionResumeOption) {
|
package/dist/structures/Utils.js
CHANGED
|
@@ -684,7 +684,6 @@ class PlayerUtils {
|
|
|
684
684
|
const snapshot = {
|
|
685
685
|
options: player.options,
|
|
686
686
|
voiceState: player.voiceState,
|
|
687
|
-
clusterId: player.clusterId,
|
|
688
687
|
guildId: player.guildId,
|
|
689
688
|
voiceChannelId: player.voiceChannelId ?? null,
|
|
690
689
|
textChannelId: player.textChannelId ?? null,
|
|
@@ -69,5 +69,9 @@ class DiscordenoManager extends Manager_1.Manager {
|
|
|
69
69
|
username: typeof user === "string" ? undefined : user.username,
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
|
+
resolveGuild(guildId) {
|
|
73
|
+
// Try user-provided cache getter
|
|
74
|
+
return this.getGuildFromCache(guildId);
|
|
75
|
+
}
|
|
72
76
|
}
|
|
73
77
|
exports.DiscordenoManager = DiscordenoManager;
|
package/package.json
CHANGED
|
@@ -1,107 +1,107 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
2
|
+
"name": "magmastream",
|
|
3
|
+
"version": "2.9.3-dev.25",
|
|
4
|
+
"description": "A user-friendly Lavalink client designed for NodeJS.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"types": "rtb --dist dist",
|
|
13
|
+
"format": "prettier --write .",
|
|
14
|
+
"format:check": "prettier --check .",
|
|
15
|
+
"lint": "eslint \"src/**/*.{ts,js}\"",
|
|
16
|
+
"lint:fix": "eslint --fix \"src/**/*.{ts,js}\"",
|
|
17
|
+
"ci": "run-s format:check lint build types",
|
|
18
|
+
"release:dev": "npm run format && npm run lint:fix && npm run ci && npm version prerelease --preid=dev && git push && npm publish --tag dev"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@favware/rollup-type-bundler": "^4.0.0",
|
|
22
|
+
"@types/jsdom": "^28.0.0",
|
|
23
|
+
"@types/lodash": "^4.17.24",
|
|
24
|
+
"@types/node": "^25.3.0",
|
|
25
|
+
"@types/ws": "^8.18.1",
|
|
26
|
+
"@typescript-eslint/eslint-plugin": "^8.56.0",
|
|
27
|
+
"@typescript-eslint/parser": "^8.56.0",
|
|
28
|
+
"eslint": "^10.0.2",
|
|
29
|
+
"npm-run-all": "^4.1.5",
|
|
30
|
+
"prettier": "^3.8.1",
|
|
31
|
+
"typedoc": "^0.28.17",
|
|
32
|
+
"typedoc-plugin-no-inherit": "^1.6.1",
|
|
33
|
+
"typescript": "^5.9.3"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@discordjs/collection": "^2.1.1",
|
|
37
|
+
"axios": "^1.13.6",
|
|
38
|
+
"events": "^3.3.0",
|
|
39
|
+
"ioredis": "^5.10.0",
|
|
40
|
+
"jsdom": "^28.1.0",
|
|
41
|
+
"lodash": "^4.17.23",
|
|
42
|
+
"safe-stable-stringify": "^2.5.0",
|
|
43
|
+
"tslib": "^2.8.1",
|
|
44
|
+
"ws": "^8.19.0"
|
|
45
|
+
},
|
|
46
|
+
"optionalDependencies": {
|
|
47
|
+
"discord.js": "14.x",
|
|
48
|
+
"discordeno": "21.x",
|
|
49
|
+
"eris": "0.18.x",
|
|
50
|
+
"oceanic.js": "1.13.x",
|
|
51
|
+
"seyfert": "4.x"
|
|
52
|
+
},
|
|
53
|
+
"overrides": {
|
|
54
|
+
"undici": "^7.0.0"
|
|
55
|
+
},
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": ">=20.19.0"
|
|
58
|
+
},
|
|
59
|
+
"eslintConfig": {
|
|
60
|
+
"root": true,
|
|
61
|
+
"parser": "@typescript-eslint/parser",
|
|
62
|
+
"plugins": [
|
|
63
|
+
"@typescript-eslint"
|
|
64
|
+
],
|
|
65
|
+
"rules": {
|
|
66
|
+
"object-curly-spacing": [
|
|
67
|
+
"error",
|
|
68
|
+
"always"
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
"extends": [
|
|
72
|
+
"eslint:recommended",
|
|
73
|
+
"plugin:@typescript-eslint/recommended"
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
"keywords": [
|
|
77
|
+
"lavalink client",
|
|
78
|
+
"wrapper",
|
|
79
|
+
"typescript",
|
|
80
|
+
"discord.js",
|
|
81
|
+
"node.js",
|
|
82
|
+
"java",
|
|
83
|
+
"javascript",
|
|
84
|
+
"audio streaming",
|
|
85
|
+
"music bot",
|
|
86
|
+
"voice chat",
|
|
87
|
+
"discord integration",
|
|
88
|
+
"high performance",
|
|
89
|
+
"scalable",
|
|
90
|
+
"easy-to-use",
|
|
91
|
+
"feature-rich",
|
|
92
|
+
"cross-platform",
|
|
93
|
+
"seamless integration",
|
|
94
|
+
"community support",
|
|
95
|
+
"documentation",
|
|
96
|
+
"open-source",
|
|
97
|
+
"lavalink",
|
|
98
|
+
"magmastream"
|
|
99
|
+
],
|
|
100
|
+
"repository": {
|
|
101
|
+
"type": "git",
|
|
102
|
+
"url": "git+https://gitryx.com/MagmaStream/magmastream.git#main"
|
|
103
|
+
},
|
|
104
|
+
"homepage": "https://docs.magmastream.com",
|
|
105
|
+
"author": "Abel Purnwasy",
|
|
106
|
+
"license": "Apache-2.0"
|
|
107
107
|
}
|