aqualink 2.19.1 → 2.20.1

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.
@@ -1,4 +1,4 @@
1
- const https = require('https')
1
+ const https = require('node:https')
2
2
 
3
3
  // Default agent config (used only if shared agent not provided)
4
4
  const AGENT_CONFIG = {
@@ -11,7 +11,12 @@ const AGENT_CONFIG = {
11
11
 
12
12
  // Shared agent reference - can be set from Rest module
13
13
  let sharedAgent = null
14
- const getAgent = () => sharedAgent || (sharedAgent = new https.Agent(AGENT_CONFIG))
14
+ const getAgent = () => {
15
+ if (!sharedAgent) {
16
+ sharedAgent = new https.Agent(AGENT_CONFIG)
17
+ }
18
+ return sharedAgent
19
+ }
15
20
 
16
21
  // Allow Rest module to inject its agent
17
22
  const setSharedAgent = (agent) => {
@@ -20,7 +25,6 @@ const setSharedAgent = (agent) => {
20
25
  }
21
26
  }
22
27
 
23
-
24
28
  const SC_LINK_RE = /<a\s+itemprop="url"\s+href="(\/[^"]+)"/g
25
29
  const MAX_REDIRECTS = 3
26
30
  const MAX_RESPONSE_BYTES = 5 * 1024 * 1024 // 5 MB
@@ -1,4 +1,4 @@
1
- const https = require('https')
1
+ const https = require('node:https')
2
2
 
3
3
  const sourceHandlers = {
4
4
  spotify: fetchSpotifyThumbnail,
@@ -80,9 +80,7 @@ async function fetchYouTubeThumbnail(identifier) {
80
80
  try {
81
81
  const exists = await checkImageExists(url)
82
82
  if (exists) return url
83
- } catch (error) {
84
- continue
85
- }
83
+ } catch (_error) {}
86
84
  }
87
85
 
88
86
  return null
package/build/index.d.ts CHANGED
@@ -29,6 +29,7 @@ declare module 'aqualink' {
29
29
  allowedDomains: string[]
30
30
  loadBalancer: LoadBalancerStrategy
31
31
  send: (payload: any) => void
32
+ autoRegionMigrate: boolean
32
33
 
33
34
  // Internal State Management
34
35
  _nodeStates: Map<
@@ -139,12 +140,26 @@ declare module 'aqualink' {
139
140
  // Failover and Migration Methods
140
141
  handleNodeFailover(failedNode: Node): Promise<void>
141
142
 
143
+ /**
144
+ * Moves a player to a different node
145
+ * @param guildId Guild ID of the player
146
+ * @param targetNode Target node to move to
147
+ * @param reason Reason for migration (default: 'region')
148
+ */
149
+ movePlayerToNode(
150
+ guildId: string,
151
+ targetNode: Node,
152
+ reason?: string
153
+ ): Promise<Player>
154
+
142
155
  // Utility Methods
143
156
  /**
144
157
  * Destroys the Aqua instance and all players
145
158
  */
146
159
  destroy(): Promise<void>
147
160
 
161
+ getTrace(limit?: number): TraceEntry[]
162
+
148
163
  // Internal Methods
149
164
  _invalidateCache(): void
150
165
  _getCachedNodeLoad(node: Node): number
@@ -191,6 +206,8 @@ declare module 'aqualink' {
191
206
  _bindEventHandlers(): void
192
207
  _startCleanupTimer(): void
193
208
  _onNodeReady(node: Node, data: { resumed: boolean }): void
209
+ _regionMatches(configuredRegion: string, extractedRegion: string): boolean
210
+ _findBestNodeForRegion(region: string): Node | null
194
211
 
195
212
  // Optional bypass checks
196
213
  bypassChecks?: { nodeFetchInfo?: boolean }
@@ -211,7 +228,7 @@ declare module 'aqualink' {
211
228
  auth: string
212
229
  ssl: boolean
213
230
  sessionId: string | null
214
- regions: string[]
231
+ regions: DiscordVoiceRegion[]
215
232
  wsUrl: string
216
233
  rest: Rest
217
234
  resumeTimeout: number
@@ -334,7 +351,10 @@ declare module 'aqualink' {
334
351
  * await player.play(track);
335
352
  * ```
336
353
  */
337
- play(track?: Track | null, options?: { paused?: boolean; startTime?: number; noReplace?: boolean }): Promise<Player>
354
+ play(
355
+ track?: Track | null,
356
+ options?: { paused?: boolean; startTime?: number; noReplace?: boolean }
357
+ ): Promise<Player>
338
358
 
339
359
  /**
340
360
  * Connects the player to a voice channel
@@ -746,6 +766,7 @@ declare module 'aqualink' {
746
766
  _lastSentVoiceKey: string
747
767
  _lastVoiceDataUpdate: number
748
768
  _stateFlags: number
769
+ _regionMigrationAttempted: boolean
749
770
 
750
771
  // Methods
751
772
  setServerUpdate(data: VoiceServerUpdate['d']): void
@@ -762,6 +783,7 @@ declare module 'aqualink' {
762
783
  _sendUpdate(payload: any): Promise<void>
763
784
  _handleDisconnect(): void
764
785
  _clearPendingUpdate(): void
786
+ _checkRegionMigration(): void
765
787
  }
766
788
 
767
789
  export class Plugin {
@@ -813,6 +835,9 @@ declare module 'aqualink' {
813
835
  loadBalancer?: LoadBalancerStrategy
814
836
  failoverOptions?: FailoverOptions
815
837
  useHttp2?: boolean
838
+ autoRegionMigrate?: boolean
839
+ debugTrace?: boolean
840
+ traceMaxEntries?: number
816
841
  }
817
842
 
818
843
  export interface FailoverOptions {
@@ -832,7 +857,7 @@ declare module 'aqualink' {
832
857
  auth?: string
833
858
  ssl?: boolean
834
859
  sessionId?: string
835
- regions?: string[]
860
+ regions?: DiscordVoiceRegion[]
836
861
  }
837
862
 
838
863
  export interface NodeAdditionalOptions {
@@ -863,7 +888,7 @@ declare module 'aqualink' {
863
888
  deaf?: boolean
864
889
  mute?: boolean
865
890
  defaultVolume?: number
866
- region?: string
891
+ region?: DiscordVoiceRegion
867
892
  }
868
893
 
869
894
  export interface ResolveOptions {
@@ -1160,6 +1185,122 @@ declare module 'aqualink' {
1160
1185
  toFront?: boolean
1161
1186
  }
1162
1187
 
1188
+ /**
1189
+ * A map of Discord voice region codes to their string values.
1190
+ * Each entry shows the country and airport name in IntelliSense.
1191
+ *
1192
+ * Use `VoiceRegion.bom`, `VoiceRegion.gru`, etc. for full autocomplete descriptions,
1193
+ * or pass raw strings like `'bom'` directly — both are accepted by `NodeOptions.regions`.
1194
+ *
1195
+ * @example
1196
+ * ```ts
1197
+ * // With descriptions in IntelliSense
1198
+ * { host: '...', regions: [VoiceRegion.gru, VoiceRegion.eze] }
1199
+ *
1200
+ * // Raw strings also work
1201
+ * { host: '...', regions: ['gru', 'eze'] }
1202
+ * ```
1203
+ */
1204
+ export const VoiceRegion: {
1205
+ // ─── Asia Pacific ─────────────────────────────────────────────────────────
1206
+
1207
+ /** 🇮🇳 Mumbai Chhatrapati Shivaji Maharaj International */
1208
+ readonly India: 'bom'
1209
+ /** 🇸🇬 Changi Airport */
1210
+ readonly Singapore: 'sin'
1211
+ /** 🇯🇵 Tokyo Narita International */
1212
+ readonly Japan: 'nrt'
1213
+ /** 🇰🇷 Seoul Incheon International */
1214
+ readonly SouthKorea: 'icn'
1215
+ /** 🇭🇰 Hong Kong International */
1216
+ readonly HongKong: 'hkg'
1217
+ /** 🇦🇺 Sydney Kingsford Smith */
1218
+ readonly Australia: 'syd'
1219
+ /** 🇮🇩 Jakarta Soekarno-Hatta International */
1220
+ readonly Indonesia: 'cgk'
1221
+
1222
+ // ─── Europe ───────────────────────────────────────────────────────────────
1223
+
1224
+ /** 🇩🇪 Frankfurt Airport */
1225
+ readonly Germany: 'fra'
1226
+ /** 🇳🇱 Amsterdam Schiphol */
1227
+ readonly Netherlands: 'ams'
1228
+ /** 🇬🇧 London Heathrow */
1229
+ readonly UnitedKingdom: 'lhr'
1230
+ /** 🇫🇷 Paris Charles de Gaulle */
1231
+ readonly France: 'cdg'
1232
+ /** 🇪🇸 Madrid Barajas */
1233
+ readonly Spain: 'mad'
1234
+ /** 🇮🇹 Milan Malpensa */
1235
+ readonly Italy: 'mxp'
1236
+ /** 🇸🇪 Stockholm Arlanda */
1237
+ readonly Sweden: 'arn'
1238
+ /** 🇫🇮 Helsinki Vantaa */
1239
+ readonly Finland: 'hel'
1240
+ /** 🇵🇱 Warsaw Chopin */
1241
+ readonly Poland: 'waw'
1242
+ /** 🇷🇴 Bucharest Henri Coanda */
1243
+ readonly Romania: 'buh'
1244
+ /** 🇷🇺 St. Petersburg Pulkovo */
1245
+ readonly RussiaSTP: 'led'
1246
+ /** 🇷🇺 Moscow Sheremetyevo */
1247
+ readonly RussiaMoscow: 'svo'
1248
+
1249
+ // ─── Middle East & Africa ─────────────────────────────────────────────────
1250
+
1251
+ /** 🇮🇱 Tel Aviv Ben Gurion */
1252
+ readonly Israel: 'tlv'
1253
+ /** 🇦🇪 Dubai International */
1254
+ readonly UAE: 'dxb'
1255
+ /** 🇸🇦 Dammam King Fahd International */
1256
+ readonly SaudiArabia: 'dmm'
1257
+ /** 🇿🇦 Johannesburg O.R. Tambo International */
1258
+ readonly SouthAfrica: 'jnb'
1259
+
1260
+ // ─── North America ────────────────────────────────────────────────────────
1261
+
1262
+ /** 🇺🇸 Newark / New York */
1263
+ readonly USANewark: 'ewr'
1264
+ /** 🇺🇸 Washington D.C. Dulles */
1265
+ readonly USAWashington: 'iad'
1266
+ /** 🇺🇸 Atlanta Hartsfield-Jackson */
1267
+ readonly USAAtlanta: 'atl'
1268
+ /** 🇺🇸 Miami International */
1269
+ readonly USAMiami: 'mia'
1270
+ /** 🇺🇸 Chicago O'Hare */
1271
+ readonly USAChicago: 'ord'
1272
+ /** 🇺🇸 Dallas/Fort Worth */
1273
+ readonly USADallas: 'dfw'
1274
+ /** 🇺🇸 Seattle-Tacoma / Oregon */
1275
+ readonly USASeattle: 'sea'
1276
+ /** 🇺🇸 Los Angeles International */
1277
+ readonly USALosAngeles: 'lax'
1278
+ /** 🇨🇦 Toronto Pearson International */
1279
+ readonly CanadaToronto: 'yyz'
1280
+ /** 🇨🇦 Montreal Pierre Elliott Trudeau */
1281
+ readonly CanadaMontreal: 'ymq'
1282
+
1283
+ // ─── South America ────────────────────────────────────────────────────────
1284
+
1285
+ /** 🇧🇷 Sao Paulo Guarulhos International */
1286
+ readonly Brazil: 'gru'
1287
+ /** 🇨🇱 Santiago Arturo Merino Benitez */
1288
+ readonly Chile: 'scl'
1289
+ /** 🇦🇷 Buenos Aires Ministro Pistarini */
1290
+ readonly Argentina: 'eze'
1291
+ }
1292
+
1293
+ /**
1294
+ * Discord voice server region prefix (derived from IATA airport codes).
1295
+ * Used in `NodeOptions.regions` to match players to the best Lavalink node
1296
+ * based on Discord's voice endpoint (e.g. `c-bom06-xxxx.discord.media` -> `'bom'`).
1297
+ *
1298
+ * For descriptions on each value, use the `VoiceRegion` object in your IDE.
1299
+ */
1300
+ export type DiscordVoiceRegion =
1301
+ | (typeof VoiceRegion)[keyof typeof VoiceRegion]
1302
+ | (string & {})
1303
+
1163
1304
  // Type Unions and Enums
1164
1305
  export type SearchSource =
1165
1306
  | 'ytsearch'
package/build/index.js CHANGED
@@ -9,6 +9,53 @@ const Rest = require('./structures/Rest')
9
9
  const Track = require('./structures/Track')
10
10
  const { AqualinkEvents } = require('./structures/AqualinkEvents')
11
11
 
12
+ const VoiceRegion = Object.freeze({
13
+ // ─── Asia Pacific ─────────────────────────────────────────────────────────
14
+ India: 'bom',
15
+ Singapore: 'sin',
16
+ Japan: 'nrt',
17
+ SouthKorea: 'icn',
18
+ HongKong: 'hkg',
19
+ Australia: 'syd',
20
+ Indonesia: 'cgk',
21
+
22
+ // ─── Europe ───────────────────────────────────────────────────────────────
23
+ Germany: 'fra',
24
+ Netherlands: 'ams',
25
+ UnitedKingdom: 'lhr',
26
+ France: 'cdg',
27
+ Spain: 'mad',
28
+ Italy: 'mxp',
29
+ Sweden: 'arn',
30
+ Finland: 'hel',
31
+ Poland: 'waw',
32
+ Romania: 'buh',
33
+ RussiaSTP: 'led',
34
+ RussiaMoscow: 'svo',
35
+
36
+ // ─── Middle East & Africa ─────────────────────────────────────────────────
37
+ Israel: 'tlv',
38
+ UAE: 'dxb',
39
+ SaudiArabia: 'dmm',
40
+ SouthAfrica: 'jnb',
41
+
42
+ // ─── North America ────────────────────────────────────────────────────────
43
+ USANewark: 'ewr',
44
+ USAWashington: 'iad',
45
+ USAAtlanta: 'atl',
46
+ USAMiami: 'mia',
47
+ USAChicago: 'ord',
48
+ USADallas: 'dfw',
49
+ USASeattle: 'sea',
50
+ USALosAngeles: 'lax',
51
+ CanadaToronto: 'yyz',
52
+ CanadaMontreal: 'ymq',
53
+
54
+ Brazil: 'gru' || 'brazil', // i only know this endpoint lol.
55
+ Chile: 'scl' || 'chile',
56
+ Argentina: 'eze' || 'argentina'
57
+ })
58
+
12
59
  module.exports = {
13
60
  Connection,
14
61
  Filters,
@@ -19,5 +66,6 @@ module.exports = {
19
66
  Queue,
20
67
  Rest,
21
68
  Track,
69
+ VoiceRegion,
22
70
  AqualinkEvents
23
71
  }