magmastream 2.5.1 → 2.5.3

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/README.md CHANGED
@@ -43,6 +43,7 @@ Also you can join the [Discord Support Server](https://discord.com/invite/HV59Z3
43
43
  | [Stal](https://discord.com/oauth2/authorize?client_id=923938180263182356&scope=bot%20applications.commands&permissions=27648861246) | memte |
44
44
  | [Lunio](https://discord.com/api/oauth2/authorize?client_id=945030475779551415&permissions=61991952&scope=bot+applications.commands) | vexi |
45
45
  | [JukeDisc](https://discord.com/oauth2/authorize?client_id=1109751797549105176&permissions=968552214080&scope=bot+applications.commands) | Theo |
46
+ | [Cool Music](https://discord.com/oauth2/authorize?client_id=923529398425096193&permissions=12888394808&redirect_uri=https%3A%2F%2Fdiscord.gg%2Fcool-music-support-925619107460698202&response_type=code&scope=bot%20identify%20applications.commands) | Itz Random |
46
47
 
47
48
  If you want to add your own bot create a pull request with your bot added. Please add your full name.
48
49
 
package/dist/index.d.ts CHANGED
@@ -328,11 +328,11 @@ interface Track {
328
328
  /** The track source name. */
329
329
  readonly sourceName: TrackSourceName;
330
330
  /** The title of the track. */
331
- readonly title: string;
331
+ title: string;
332
332
  /** The identifier of the track. */
333
333
  readonly identifier: string;
334
334
  /** The author of the track. */
335
- readonly author: string;
335
+ author: string;
336
336
  /** The duration of the track. */
337
337
  readonly duration: number;
338
338
  /** If the track is seekable. */
@@ -349,6 +349,8 @@ interface Track {
349
349
  displayThumbnail(size?: Sizes): string;
350
350
  /** Additional track info provided by plugins. */
351
351
  pluginInfo: TrackPluginInfo;
352
+ /** Add your own data to the track. */
353
+ customData: Record<string, unknown>;
352
354
  }
353
355
  interface TrackPluginInfo {
354
356
  albumName?: string;
@@ -830,6 +832,8 @@ interface ManagerOptions {
830
832
  trackPartial?: string[];
831
833
  /** The default search platform to use, can be "youtube", "youtube music", "soundcloud" or deezer. */
832
834
  defaultSearchPlatform?: SearchPlatform;
835
+ /** Whether the YouTube video titles should be replaced if the Author does not exactly match. */
836
+ replaceYouTubeCredentials?: boolean;
833
837
  /**
834
838
  * Function to send data to the websocket.
835
839
  * @param id
@@ -890,20 +894,12 @@ interface ManagerEvents {
890
894
  playerStateUpdate: [oldPlayer: Player, newPlayer: Player];
891
895
  playerMove: [player: Player, initChannel: string, newChannel: string];
892
896
  playerDisconnect: [player: Player, oldChannel: string];
893
- queueEnd: [
894
- player: Player,
895
- track: Track | UnresolvedTrack,
896
- payload: TrackEndEvent
897
- ];
897
+ queueEnd: [player: Player, track: Track | UnresolvedTrack, payload: TrackEndEvent];
898
898
  socketClosed: [player: Player, payload: WebSocketClosedEvent];
899
899
  trackStart: [player: Player, track: Track, payload: TrackStartEvent];
900
900
  trackEnd: [player: Player, track: Track, payload: TrackEndEvent];
901
901
  trackStuck: [player: Player, track: Track, payload: TrackStuckEvent];
902
- trackError: [
903
- player: Player,
904
- track: Track | UnresolvedTrack,
905
- payload: TrackExceptionEvent
906
- ];
902
+ trackError: [player: Player, track: Track | UnresolvedTrack, payload: TrackExceptionEvent];
907
903
  }
908
904
 
909
905
  export { type CPUStats, type EqualizerBand, type Exception, type Extendable, type FrameStats, type LavalinkResponse, type LoadType, Manager, type ManagerEvents, type ManagerOptions, type MemoryStats, Node, type NodeMessage, type NodeOptions, type NodeStats, type Payload, type PlayOptions, Player, type PlayerEvent, type PlayerEventType, type PlayerEvents, type PlayerOptions, type PlayerUpdate, type PlaylistData, type PlaylistRawData, Plugin, Queue, type SearchPlatform, type SearchQuery, type SearchResult, type Severity, type Sizes, type State, Structure, type Track, type TrackData, type TrackDataInfo, type TrackEndEvent, type TrackEndReason, type TrackExceptionEvent, type TrackPluginInfo, type TrackSourceName, type TrackStartEvent, type TrackStuckEvent, TrackUtils, type UnresolvedQuery, type UnresolvedTrack, type VoicePacket, type VoiceServer, type VoiceState, type WebSocketClosedEvent };
@@ -36,7 +36,7 @@ class Filters {
36
36
  };
37
37
  }
38
38
  async updateFilters() {
39
- const { distortion, equalizer, karaoke, rotation, timescale, vibrato, volume, } = this;
39
+ const { distortion, equalizer, karaoke, rotation, timescale, vibrato, volume } = this;
40
40
  await this.player.node.rest.updatePlayer({
41
41
  data: {
42
42
  filters: {
@@ -109,9 +109,7 @@ class Filters {
109
109
  }
110
110
  /** Applies the vaporwave effect. */
111
111
  vaporwave() {
112
- return this.setEqualizer(filtersEqualizers_1.vaporwaveEqualizer)
113
- .setTimescale({ pitch: 0.55 })
114
- .setFilterStatus("vaporwave", true);
112
+ return this.setEqualizer(filtersEqualizers_1.vaporwaveEqualizer).setTimescale({ pitch: 0.55 }).setFilterStatus("vaporwave", true);
115
113
  }
116
114
  /** Applies the distortion audio effect. */
117
115
  distort() {
@@ -32,20 +32,14 @@ class Manager extends events_1.EventEmitter {
32
32
  return this.nodes
33
33
  .filter((node) => node.connected)
34
34
  .sort((a, b) => {
35
- const aload = a.stats.cpu
36
- ? (a.stats.cpu.lavalinkLoad / a.stats.cpu.cores) * 100
37
- : 0;
38
- const bload = b.stats.cpu
39
- ? (b.stats.cpu.lavalinkLoad / b.stats.cpu.cores) * 100
40
- : 0;
35
+ const aload = a.stats.cpu ? (a.stats.cpu.lavalinkLoad / a.stats.cpu.cores) * 100 : 0;
36
+ const bload = b.stats.cpu ? (b.stats.cpu.lavalinkLoad / b.stats.cpu.cores) * 100 : 0;
41
37
  return aload - bload;
42
38
  });
43
39
  }
44
40
  /** Returns the nodes that has the least amount of players. */
45
41
  get leastPlayersNode() {
46
- return this.nodes
47
- .filter((node) => node.connected)
48
- .sort((a, b) => a.stats.players - b.stats.players);
42
+ return this.nodes.filter((node) => node.connected).sort((a, b) => a.stats.players - b.stats.players);
49
43
  }
50
44
  /** Returns a node based on priority. */
51
45
  get priorityNode() {
@@ -63,17 +57,11 @@ class Manager extends events_1.EventEmitter {
63
57
  return node;
64
58
  }
65
59
  }
66
- return this.options.useNode === "leastLoad"
67
- ? this.leastLoadNode.first()
68
- : this.leastPlayersNode.first();
60
+ return this.options.useNode === "leastLoad" ? this.leastLoadNode.first() : this.leastPlayersNode.first();
69
61
  }
70
62
  /** Returns the node to use. */
71
63
  get useableNodes() {
72
- return this.options.usePriority
73
- ? this.priorityNode
74
- : this.options.useNode === "leastLoad"
75
- ? this.leastLoadNode.first()
76
- : this.leastPlayersNode.first();
64
+ return this.options.usePriority ? this.priorityNode : this.options.useNode === "leastLoad" ? this.leastLoadNode.first() : this.leastPlayersNode.first();
77
65
  }
78
66
  /**
79
67
  * Initiates the Manager class.
@@ -179,23 +167,43 @@ class Manager extends events_1.EventEmitter {
179
167
  break;
180
168
  }
181
169
  const tracks = searchData.map((track) => Utils_1.TrackUtils.build(track, requester));
182
- const playlist = res.loadType === "playlist"
183
- ? {
170
+ let playlist = null;
171
+ if (res.loadType === "playlist") {
172
+ playlist = {
184
173
  name: playlistData.info.name,
185
174
  tracks: playlistData.tracks.map((track) => Utils_1.TrackUtils.build(track, requester)),
186
175
  duration: playlistData.tracks.reduce((acc, cur) => acc + (cur.info.length || 0), 0),
187
- }
188
- : null;
176
+ };
177
+ }
189
178
  const result = {
190
179
  loadType: res.loadType,
191
180
  tracks,
192
181
  playlist,
193
182
  };
183
+ if (this.options.replaceYouTubeCredentials) {
184
+ let tracksToReplace = [];
185
+ if (result.loadType === "playlist") {
186
+ tracksToReplace = result.playlist.tracks;
187
+ }
188
+ else {
189
+ tracksToReplace = result.tracks;
190
+ }
191
+ for (const track of tracksToReplace) {
192
+ if (isYouTubeURL(track.uri) && track.title.includes("-")) {
193
+ const [author, title] = track.title.split("-").map((str) => str.trim());
194
+ track.author = author;
195
+ track.title = title.replace("Topic -", "");
196
+ }
197
+ }
198
+ }
194
199
  return result;
195
200
  }
196
201
  catch (err) {
197
202
  throw new Error(err);
198
203
  }
204
+ function isYouTubeURL(uri) {
205
+ return uri.includes("youtube.com") || uri.includes("youtu.be");
206
+ }
199
207
  }
200
208
  /**
201
209
  * Decodes the base64 encoded tracks and returns a TrackData array.
@@ -206,9 +214,7 @@ class Manager extends events_1.EventEmitter {
206
214
  const node = this.nodes.first();
207
215
  if (!node)
208
216
  throw new Error("No available nodes.");
209
- const res = (await node.rest
210
- .post("/v4/decodetracks", JSON.stringify(tracks))
211
- .catch((err) => reject(err)));
217
+ const res = (await node.rest.post("/v4/decodetracks", JSON.stringify(tracks)).catch((err) => reject(err)));
212
218
  if (!res) {
213
219
  return reject(new Error("No data returned from query."));
214
220
  }
@@ -273,8 +279,7 @@ class Manager extends events_1.EventEmitter {
273
279
  * @param data
274
280
  */
275
281
  async updateVoiceState(data) {
276
- if ("t" in data &&
277
- !["VOICE_STATE_UPDATE", "VOICE_SERVER_UPDATE"].includes(data.t))
282
+ if ("t" in data && !["VOICE_STATE_UPDATE", "VOICE_SERVER_UPDATE"].includes(data.t))
278
283
  return;
279
284
  const update = "d" in data ? data.d : data;
280
285
  if (!update || (!("token" in update) && !("session_id" in update)))
@@ -271,9 +271,7 @@ class Node {
271
271
  if (res.loadType === "playlist") {
272
272
  tracks = res.playlist.tracks;
273
273
  }
274
- const foundTrack = tracks
275
- .sort(() => Math.random() - 0.5)
276
- .find((shuffledTrack) => shuffledTrack.uri !== track.uri);
274
+ const foundTrack = tracks.sort(() => Math.random() - 0.5).find((shuffledTrack) => shuffledTrack.uri !== track.uri);
277
275
  if (foundTrack) {
278
276
  player.queue.add(foundTrack);
279
277
  player.play();
@@ -183,8 +183,7 @@ class Player {
183
183
  return (this.nowPlayingMessage = message);
184
184
  }
185
185
  async play(optionsOrTrack, playOptions) {
186
- if (typeof optionsOrTrack !== "undefined" &&
187
- Utils_1.TrackUtils.validate(optionsOrTrack)) {
186
+ if (typeof optionsOrTrack !== "undefined" && Utils_1.TrackUtils.validate(optionsOrTrack)) {
188
187
  if (this.queue.current)
189
188
  this.queue.previous = this.queue.current;
190
189
  this.queue.current = optionsOrTrack;
@@ -4,16 +4,7 @@ exports.Plugin = exports.Structure = exports.TrackUtils = void 0;
4
4
  /** @hidden */
5
5
  const TRACK_SYMBOL = Symbol("track"),
6
6
  /** @hidden */
7
- UNRESOLVED_TRACK_SYMBOL = Symbol("unresolved"), SIZES = [
8
- "0",
9
- "1",
10
- "2",
11
- "3",
12
- "default",
13
- "mqdefault",
14
- "hqdefault",
15
- "maxresdefault",
16
- ];
7
+ UNRESOLVED_TRACK_SYMBOL = Symbol("unresolved"), SIZES = ["0", "1", "2", "3", "default", "mqdefault", "hqdefault", "maxresdefault"];
17
8
  /** @hidden */
18
9
  const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
19
10
  class TrackUtils {
@@ -24,8 +15,7 @@ class TrackUtils {
24
15
  this.manager = manager;
25
16
  }
26
17
  static setTrackPartial(partial) {
27
- if (!Array.isArray(partial) ||
28
- !partial.every((str) => typeof str === "string"))
18
+ if (!Array.isArray(partial) || !partial.every((str) => typeof str === "string"))
29
19
  throw new Error("Provided partial is not an array or not a string array.");
30
20
  if (!partial.includes("track"))
31
21
  partial.unshift("track");
@@ -45,8 +35,7 @@ class TrackUtils {
45
35
  }
46
36
  return true;
47
37
  }
48
- return ((trackOrTracks[TRACK_SYMBOL] ||
49
- trackOrTracks[UNRESOLVED_TRACK_SYMBOL]) === true);
38
+ return (trackOrTracks[TRACK_SYMBOL] || trackOrTracks[UNRESOLVED_TRACK_SYMBOL]) === true;
50
39
  }
51
40
  /**
52
41
  * Checks if the provided argument is a valid UnresolvedTrack.
@@ -86,14 +75,10 @@ class TrackUtils {
86
75
  uri: data.info.uri,
87
76
  artworkUrl: data.info?.artworkUrl,
88
77
  sourceName: data.info?.sourceName,
89
- thumbnail: data.info.uri.includes("youtube")
90
- ? `https://img.youtube.com/vi/${data.info.identifier}/default.jpg`
91
- : null,
78
+ thumbnail: data.info.uri.includes("youtube") ? `https://img.youtube.com/vi/${data.info.identifier}/default.jpg` : null,
92
79
  displayThumbnail(size = "default") {
93
80
  const finalSize = SIZES.find((s) => s === size) ?? "default";
94
- return this.uri.includes("youtube")
95
- ? `https://img.youtube.com/vi/${data.info.identifier}/${finalSize}.jpg`
96
- : null;
81
+ return this.uri.includes("youtube") ? `https://img.youtube.com/vi/${data.info.identifier}/${finalSize}.jpg` : null;
97
82
  },
98
83
  requester,
99
84
  pluginInfo: {
@@ -104,6 +89,7 @@ class TrackUtils {
104
89
  isPreview: data.pluginInfo?.isPreview,
105
90
  previewUrl: data.pluginInfo?.previewUrl,
106
91
  },
92
+ customData: {},
107
93
  };
108
94
  track.displayThumbnail = track.displayThumbnail.bind(track);
109
95
  if (this.trackPartial) {
@@ -154,17 +140,10 @@ class TrackUtils {
154
140
  throw new RangeError("Manager has not been initiated.");
155
141
  if (!TrackUtils.isUnresolvedTrack(unresolvedTrack))
156
142
  throw new RangeError("Provided track is not a UnresolvedTrack.");
157
- const query = unresolvedTrack.uri
158
- ? unresolvedTrack.uri
159
- : [unresolvedTrack.author, unresolvedTrack.title]
160
- .filter(Boolean)
161
- .join(" - ");
143
+ const query = unresolvedTrack.uri ? unresolvedTrack.uri : [unresolvedTrack.author, unresolvedTrack.title].filter(Boolean).join(" - ");
162
144
  const res = await TrackUtils.manager.search(query, unresolvedTrack.requester);
163
145
  if (unresolvedTrack.author) {
164
- const channelNames = [
165
- unresolvedTrack.author,
166
- `${unresolvedTrack.author} - Topic`,
167
- ];
146
+ const channelNames = [unresolvedTrack.author, `${unresolvedTrack.author} - Topic`];
168
147
  const originalAudio = res.tracks.find((track) => {
169
148
  return (channelNames.some((name) => new RegExp(`^${escapeRegExp(name)}$`, "i").test(track.author)) ||
170
149
  new RegExp(`^${escapeRegExp(unresolvedTrack.title)}$`, "i").test(track.title));
@@ -173,8 +152,7 @@ class TrackUtils {
173
152
  return originalAudio;
174
153
  }
175
154
  if (unresolvedTrack.duration) {
176
- const sameDuration = res.tracks.find((track) => track.duration >= unresolvedTrack.duration - 1500 &&
177
- track.duration <= unresolvedTrack.duration + 1500);
155
+ const sameDuration = res.tracks.find((track) => track.duration >= unresolvedTrack.duration - 1500 && track.duration <= unresolvedTrack.duration + 1500);
178
156
  if (sameDuration)
179
157
  return sameDuration;
180
158
  }
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  function managerCheck(options) {
4
4
  if (!options)
5
5
  throw new TypeError("ManagerOptions must not be empty.");
6
- const { autoPlay, clientId, clientName, defaultSearchPlatform, nodes, plugins, send, shards, trackPartial, usePriority, useNode, } = options;
6
+ const { autoPlay, clientId, clientName, defaultSearchPlatform, nodes, plugins, send, shards, trackPartial, usePriority, useNode, replaceYouTubeCredentials } = options;
7
7
  if (typeof autoPlay !== "undefined" && typeof autoPlay !== "boolean") {
8
8
  throw new TypeError('Manager option "autoPlay" must be a boolean.');
9
9
  }
@@ -13,8 +13,7 @@ function managerCheck(options) {
13
13
  if (typeof clientName !== "undefined" && typeof clientName !== "string") {
14
14
  throw new TypeError('Manager option "clientName" must be a string.');
15
15
  }
16
- if (typeof defaultSearchPlatform !== "undefined" &&
17
- typeof defaultSearchPlatform !== "string") {
16
+ if (typeof defaultSearchPlatform !== "undefined" && typeof defaultSearchPlatform !== "string") {
18
17
  throw new TypeError('Manager option "defaultSearchPlatform" must be a string.');
19
18
  }
20
19
  if (typeof nodes !== "undefined" && !Array.isArray(nodes)) {
@@ -50,5 +49,8 @@ function managerCheck(options) {
50
49
  throw new TypeError('Manager option must be either "leastLoad" or "leastPlayers".');
51
50
  }
52
51
  }
52
+ if (typeof replaceYouTubeCredentials !== "undefined" && typeof replaceYouTubeCredentials !== "boolean") {
53
+ throw new TypeError('Manager option "replaceYouTubeCredentials" must be a boolean.');
54
+ }
53
55
  }
54
56
  exports.default = managerCheck;
@@ -3,30 +3,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  function nodeCheck(options) {
4
4
  if (!options)
5
5
  throw new TypeError("NodeOptions must not be empty.");
6
- const { host, identifier, password, port, requestTimeout, resumeStatus, resumeTimeout, retryAmount, retryDelay, secure, priority, } = options;
6
+ const { host, identifier, password, port, requestTimeout, resumeStatus, resumeTimeout, retryAmount, retryDelay, secure, priority } = options;
7
7
  if (typeof host !== "string" || !/.+/.test(host)) {
8
8
  throw new TypeError('Node option "host" must be present and be a non-empty string.');
9
9
  }
10
10
  if (typeof identifier !== "undefined" && typeof identifier !== "string") {
11
11
  throw new TypeError('Node option "identifier" must be a non-empty string.');
12
12
  }
13
- if (typeof password !== "undefined" &&
14
- (typeof password !== "string" || !/.+/.test(password))) {
13
+ if (typeof password !== "undefined" && (typeof password !== "string" || !/.+/.test(password))) {
15
14
  throw new TypeError('Node option "password" must be a non-empty string.');
16
15
  }
17
16
  if (typeof port !== "undefined" && typeof port !== "number") {
18
17
  throw new TypeError('Node option "port" must be a number.');
19
18
  }
20
- if (typeof requestTimeout !== "undefined" &&
21
- typeof requestTimeout !== "number") {
19
+ if (typeof requestTimeout !== "undefined" && typeof requestTimeout !== "number") {
22
20
  throw new TypeError('Node option "requestTimeout" must be a number.');
23
21
  }
24
- if (typeof resumeStatus !== "undefined" &&
25
- typeof resumeStatus !== "boolean") {
22
+ if (typeof resumeStatus !== "undefined" && typeof resumeStatus !== "boolean") {
26
23
  throw new TypeError('Node option "resumeStatus" must be a boolean.');
27
24
  }
28
- if (typeof resumeTimeout !== "undefined" &&
29
- typeof resumeTimeout !== "number") {
25
+ if (typeof resumeTimeout !== "undefined" && typeof resumeTimeout !== "number") {
30
26
  throw new TypeError('Node option "resumeTimeout" must be a number.');
31
27
  }
32
28
  if (typeof retryAmount !== "undefined" && typeof retryAmount !== "number") {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  function playerCheck(options) {
4
4
  if (!options)
5
5
  throw new TypeError("PlayerOptions must not be empty.");
6
- const { guild, node, selfDeafen, selfMute, textChannel, voiceChannel, volume, } = options;
6
+ const { guild, node, selfDeafen, selfMute, textChannel, voiceChannel, volume } = options;
7
7
  if (!/^\d+$/.test(guild)) {
8
8
  throw new TypeError('Player option "guild" must be present and be a non-empty string.');
9
9
  }
package/package.json CHANGED
@@ -1,90 +1,90 @@
1
1
  {
2
- "name": "magmastream",
3
- "version": "2.5.1",
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
- "lint": "eslint --ext .ts ./src",
14
- "ci": "run-s lint build types"
15
- },
16
- "devDependencies": {
17
- "@favware/rollup-type-bundler": "^3.3.0",
18
- "@types/lodash": "^4.17.0",
19
- "@types/node": "^20.12.7",
20
- "@types/ws": "^8.5.10",
21
- "@typescript-eslint/eslint-plugin": "^7.7.1",
22
- "@typescript-eslint/parser": "^7.7.1",
23
- "eslint": "^8.57.0",
24
- "npm-run-all": "^4.1.5",
25
- "typedoc": "^0.25.13",
26
- "typedoc-plugin-no-inherit": "^1.4.0",
27
- "typescript": "^5.4.5"
28
- },
29
- "dependencies": {
30
- "@discordjs/collection": "^2.0.0",
31
- "axios": "^1.6.8",
32
- "events": "^3.3.0",
33
- "lodash": "^4.17.21",
34
- "tslib": "^2.6.2",
35
- "ws": "^8.17.0"
36
- },
37
- "peerDependencies": {
38
- "discord.js": ">=13.0.0 <15.0.0"
39
- },
40
- "engines": {
41
- "node": ">=16.0.0"
42
- },
43
- "eslintConfig": {
44
- "root": true,
45
- "parser": "@typescript-eslint/parser",
46
- "plugins": [
47
- "@typescript-eslint"
48
- ],
49
- "rules": {
50
- "object-curly-spacing": [
51
- "error",
52
- "always"
53
- ]
54
- },
55
- "extends": [
56
- "eslint:recommended",
57
- "plugin:@typescript-eslint/recommended"
58
- ]
59
- },
60
- "keywords": [
61
- "lavalink client",
62
- "wrapper",
63
- "typescript",
64
- "discord.js",
65
- "node.js",
66
- "java",
67
- "javascript",
68
- "audio streaming",
69
- "music bot",
70
- "voice chat",
71
- "discord integration",
72
- "high performance",
73
- "scalable",
74
- "easy-to-use",
75
- "feature-rich",
76
- "cross-platform",
77
- "seamless integration",
78
- "community support",
79
- "documentation",
80
- "open-source",
81
- "lavalink",
82
- "magmastream"
83
- ],
84
- "repository": {
85
- "url": "https://github.com/Blackfort-Hosting/magmastream/tree/main"
86
- },
87
- "homepage": "https://docs.blackforthosting.com",
88
- "author": "Abel Purnwasy",
89
- "license": "Apache-2.0"
2
+ "name": "magmastream",
3
+ "version": "2.5.3",
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
+ "lint": "eslint --ext .ts ./src",
14
+ "ci": "run-s lint build types"
15
+ },
16
+ "devDependencies": {
17
+ "@favware/rollup-type-bundler": "^3.3.0",
18
+ "@types/lodash": "^4.17.4",
19
+ "@types/node": "^20.12.12",
20
+ "@types/ws": "^8.5.10",
21
+ "@typescript-eslint/eslint-plugin": "^7.9.0",
22
+ "@typescript-eslint/parser": "^7.9.0",
23
+ "eslint": "^8.57.0",
24
+ "npm-run-all": "^4.1.5",
25
+ "typedoc": "^0.25.13",
26
+ "typedoc-plugin-no-inherit": "^1.4.0",
27
+ "typescript": "^5.4.5"
28
+ },
29
+ "dependencies": {
30
+ "@discordjs/collection": "^2.1.0",
31
+ "axios": "^1.6.8",
32
+ "events": "^3.3.0",
33
+ "lodash": "^4.17.21",
34
+ "tslib": "^2.6.2",
35
+ "ws": "^8.17.0"
36
+ },
37
+ "peerDependencies": {
38
+ "discord.js": ">=13.0.0 <15.0.0"
39
+ },
40
+ "engines": {
41
+ "node": ">=16.0.0"
42
+ },
43
+ "eslintConfig": {
44
+ "root": true,
45
+ "parser": "@typescript-eslint/parser",
46
+ "plugins": [
47
+ "@typescript-eslint"
48
+ ],
49
+ "rules": {
50
+ "object-curly-spacing": [
51
+ "error",
52
+ "always"
53
+ ]
54
+ },
55
+ "extends": [
56
+ "eslint:recommended",
57
+ "plugin:@typescript-eslint/recommended"
58
+ ]
59
+ },
60
+ "keywords": [
61
+ "lavalink client",
62
+ "wrapper",
63
+ "typescript",
64
+ "discord.js",
65
+ "node.js",
66
+ "java",
67
+ "javascript",
68
+ "audio streaming",
69
+ "music bot",
70
+ "voice chat",
71
+ "discord integration",
72
+ "high performance",
73
+ "scalable",
74
+ "easy-to-use",
75
+ "feature-rich",
76
+ "cross-platform",
77
+ "seamless integration",
78
+ "community support",
79
+ "documentation",
80
+ "open-source",
81
+ "lavalink",
82
+ "magmastream"
83
+ ],
84
+ "repository": {
85
+ "url": "https://github.com/Blackfort-Hosting/magmastream/tree/main"
86
+ },
87
+ "homepage": "https://docs.blackforthosting.com",
88
+ "author": "Abel Purnwasy",
89
+ "license": "Apache-2.0"
90
90
  }