lavalink-client 2.3.3 → 2.3.5

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.
Files changed (60) hide show
  1. package/README.md +211 -24
  2. package/dist/cjs/index.d.ts +16 -16
  3. package/dist/cjs/index.js +16 -16
  4. package/dist/cjs/package.json +3 -0
  5. package/dist/cjs/structures/Constants.d.ts +2 -1
  6. package/dist/cjs/structures/Constants.js +1 -0
  7. package/dist/cjs/structures/CustomSearches/BandCampSearch.d.ts +2 -2
  8. package/dist/cjs/structures/Filters.d.ts +2 -2
  9. package/dist/cjs/structures/Filters.js +1 -1
  10. package/dist/cjs/structures/LavalinkManager.d.ts +6 -6
  11. package/dist/cjs/structures/LavalinkManager.js +5 -5
  12. package/dist/cjs/structures/LavalinkManagerStatics.d.ts +1 -1
  13. package/dist/cjs/structures/Node.d.ts +6 -6
  14. package/dist/cjs/structures/Node.js +10 -3
  15. package/dist/cjs/structures/NodeManager.d.ts +5 -5
  16. package/dist/cjs/structures/NodeManager.js +5 -5
  17. package/dist/cjs/structures/Player.d.ts +10 -10
  18. package/dist/cjs/structures/Player.js +37 -14
  19. package/dist/cjs/structures/Queue.d.ts +3 -3
  20. package/dist/cjs/structures/Queue.js +1 -1
  21. package/dist/cjs/structures/Types/Filters.d.ts +1 -1
  22. package/dist/cjs/structures/Types/Manager.d.ts +7 -7
  23. package/dist/cjs/structures/Types/Node.d.ts +3 -3
  24. package/dist/cjs/structures/Types/Player.d.ts +5 -5
  25. package/dist/cjs/structures/Types/Queue.d.ts +1 -1
  26. package/dist/cjs/structures/Types/Track.d.ts +3 -3
  27. package/dist/cjs/structures/Types/Utils.d.ts +5 -5
  28. package/dist/cjs/structures/Utils.d.ts +6 -6
  29. package/dist/cjs/structures/Utils.js +23 -7
  30. package/dist/esm/index.d.ts +16 -16
  31. package/dist/esm/index.js +16 -16
  32. package/dist/esm/package.json +3 -0
  33. package/dist/esm/structures/Constants.d.ts +2 -1
  34. package/dist/esm/structures/Constants.js +1 -0
  35. package/dist/esm/structures/CustomSearches/BandCampSearch.d.ts +2 -2
  36. package/dist/esm/structures/Filters.d.ts +2 -2
  37. package/dist/esm/structures/Filters.js +1 -1
  38. package/dist/esm/structures/LavalinkManager.d.ts +6 -6
  39. package/dist/esm/structures/LavalinkManager.js +5 -5
  40. package/dist/esm/structures/LavalinkManagerStatics.d.ts +1 -1
  41. package/dist/esm/structures/Node.d.ts +6 -6
  42. package/dist/esm/structures/Node.js +10 -3
  43. package/dist/esm/structures/NodeManager.d.ts +5 -5
  44. package/dist/esm/structures/NodeManager.js +4 -4
  45. package/dist/esm/structures/Player.d.ts +10 -10
  46. package/dist/esm/structures/Player.js +37 -14
  47. package/dist/esm/structures/Queue.d.ts +3 -3
  48. package/dist/esm/structures/Queue.js +1 -1
  49. package/dist/esm/structures/Types/Filters.d.ts +1 -1
  50. package/dist/esm/structures/Types/Manager.d.ts +7 -7
  51. package/dist/esm/structures/Types/Node.d.ts +3 -3
  52. package/dist/esm/structures/Types/Player.d.ts +5 -5
  53. package/dist/esm/structures/Types/Queue.d.ts +1 -1
  54. package/dist/esm/structures/Types/Track.d.ts +3 -3
  55. package/dist/esm/structures/Types/Utils.d.ts +5 -5
  56. package/dist/esm/structures/Utils.d.ts +6 -6
  57. package/dist/esm/structures/Utils.js +23 -7
  58. package/dist/types/structures/Constants.d.ts +1 -0
  59. package/dist/types/structures/NodeManager.d.ts +1 -1
  60. package/package.json +13 -6
@@ -1,8 +1,8 @@
1
- import { DebugEvents } from "./Constants";
2
- import { bandCampSearch } from "./CustomSearches/BandCampSearch";
3
- import { FilterManager } from "./Filters";
4
- import { Queue, QueueSaver } from "./Queue";
5
- import { queueTrackEnd } from "./Utils";
1
+ import { DebugEvents } from "./Constants.js";
2
+ import { bandCampSearch } from "./CustomSearches/BandCampSearch.js";
3
+ import { FilterManager } from "./Filters.js";
4
+ import { Queue, QueueSaver } from "./Queue.js";
5
+ import { queueTrackEnd } from "./Utils.js";
6
6
  export class Player {
7
7
  /** Filter Manager per player */
8
8
  filterManager;
@@ -135,7 +135,7 @@ export class Player {
135
135
  */
136
136
  async play(options = {}) {
137
137
  if (this.get("internal_queueempty")) {
138
- if (typeof this.options.node === "string" && this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
138
+ if (this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
139
139
  this.LavalinkManager.emit("debug", DebugEvents.PlayerPlayQueueEmptyTimeoutClear, {
140
140
  state: "log",
141
141
  message: `Player was called to play something, while there was a queueEmpty Timeout set, clearing the timeout.`,
@@ -147,8 +147,31 @@ export class Player {
147
147
  }
148
148
  // if clientTrack provided, override options.track object
149
149
  if (options?.clientTrack && (this.LavalinkManager.utils.isTrack(options?.clientTrack) || this.LavalinkManager.utils.isUnresolvedTrack(options.clientTrack))) {
150
- if (this.LavalinkManager.utils.isUnresolvedTrack(options.clientTrack))
151
- await options.clientTrack.resolve(this);
150
+ if (this.LavalinkManager.utils.isUnresolvedTrack(options.clientTrack)) {
151
+ try {
152
+ // resolve the unresolved track
153
+ await options.clientTrack.resolve(this);
154
+ }
155
+ catch (error) {
156
+ if (this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
157
+ this.LavalinkManager.emit("debug", DebugEvents.PlayerPlayUnresolvedTrackFailed, {
158
+ state: "error",
159
+ error: error,
160
+ message: `Player Play was called with clientTrack, Song is unresolved, but couldn't resolve it`,
161
+ functionLayer: "Player > play() > resolve currentTrack",
162
+ });
163
+ }
164
+ this.LavalinkManager.emit("trackError", this, this.queue.current, error);
165
+ if (options && "clientTrack" in options)
166
+ delete options.clientTrack;
167
+ if (options && "track" in options)
168
+ delete options.track;
169
+ // try to play the next track if possible
170
+ if (this.LavalinkManager.options?.autoSkipOnResolveError === true && this.queue.tracks[0])
171
+ return this.play(options);
172
+ return this;
173
+ }
174
+ }
152
175
  if ((typeof options.track?.userData === "object" || typeof options.clientTrack?.userData === "object") && options.clientTrack)
153
176
  options.clientTrack.userData = { ...(options?.clientTrack.userData || {}), ...(options.track?.userData || {}) };
154
177
  options.track = {
@@ -182,7 +205,7 @@ export class Player {
182
205
  ...(track.userData || {}),
183
206
  requester: this.LavalinkManager.utils.getTransformedRequester(options?.track?.requester || {})
184
207
  };
185
- if (typeof this.options.node === "string" && this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
208
+ if (this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
186
209
  this.LavalinkManager.emit("debug", DebugEvents.PlayerPlayWithTrackReplace, {
187
210
  state: "log",
188
211
  message: `Player was called to play something, with a specific track provided. Replacing the current Track and resolving the track on trackStart Event.`,
@@ -206,7 +229,7 @@ export class Player {
206
229
  if (!this.queue.current && this.queue.tracks.length)
207
230
  await queueTrackEnd(this);
208
231
  if (this.queue.current && this.LavalinkManager.utils.isUnresolvedTrack(this.queue.current)) {
209
- if (typeof this.options.node === "string" && this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
232
+ if (this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
210
233
  this.LavalinkManager.emit("debug", DebugEvents.PlayerPlayUnresolvedTrack, {
211
234
  state: "log",
212
235
  message: `Player Play was called, current Queue Song is unresolved, resolving the track.`,
@@ -220,7 +243,7 @@ export class Player {
220
243
  this.queue.current.userData = { ...(this.queue.current?.userData || {}), ...(options.track?.userData || {}) };
221
244
  }
222
245
  catch (error) {
223
- if (typeof this.options.node === "string" && this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
246
+ if (this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
224
247
  this.LavalinkManager.emit("debug", DebugEvents.PlayerPlayUnresolvedTrackFailed, {
225
248
  state: "error",
226
249
  error: error,
@@ -294,7 +317,7 @@ export class Player {
294
317
  : this.volume), 1000), 0));
295
318
  const now = performance.now();
296
319
  if (this.LavalinkManager.options.playerOptions.applyVolumeAsFilter) {
297
- if (typeof this.options.node === "string" && this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
320
+ if (this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
298
321
  this.LavalinkManager.emit("debug", DebugEvents.PlayerVolumeAsFilter, {
299
322
  state: "log",
300
323
  message: `Player Volume was set as a Filter, because LavalinkManager option "playerOptions.applyVolumeAsFilter" is true`,
@@ -346,7 +369,7 @@ export class Player {
346
369
  async search(query, requestUser, throwOnEmpty = false) {
347
370
  const Query = this.LavalinkManager.utils.transformQuery(query);
348
371
  if (["bcsearch", "bandcamp"].includes(Query.source) && !this.node.info.sourceManagers.includes("bandcamp")) {
349
- if (typeof this.options.node === "string" && this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
372
+ if (this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
350
373
  this.LavalinkManager.emit("debug", DebugEvents.BandcampSearchLokalEngine, {
351
374
  state: "log",
352
375
  message: `Player.search was called with a Bandcamp Query, but no bandcamp search was enabled on lavalink, searching with the custom Search Engine.`,
@@ -556,7 +579,7 @@ export class Player {
556
579
  const updateNode = typeof newNode === "string" ? this.LavalinkManager.nodeManager.nodes.get(newNode) : newNode;
557
580
  if (!updateNode)
558
581
  throw new Error("Could not find the new Node");
559
- if (typeof this.options.node === "string" && this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
582
+ if (this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
560
583
  this.LavalinkManager.emit("debug", DebugEvents.PlayerChangeNode, {
561
584
  state: "log",
562
585
  message: `Player.changeNode() was executed, trying to change from "${this.node.id}" to "${updateNode.id}"`,
@@ -1,6 +1,6 @@
1
- import { MiniMap } from "./Utils";
2
- import type { Track, UnresolvedTrack } from "./Types/Track";
3
- import type { ManagerQueueOptions, QueueStoreManager, StoredQueue } from "./Types/Queue";
1
+ import { MiniMap } from "./Utils.js";
2
+ import type { Track, UnresolvedTrack } from "./Types/Track.js";
3
+ import type { ManagerQueueOptions, QueueStoreManager, StoredQueue } from "./Types/Queue.js";
4
4
  export declare class QueueSaver {
5
5
  /**
6
6
  * The queue store manager
@@ -1,4 +1,4 @@
1
- import { ManagerUtils, MiniMap, QueueSymbol } from "./Utils";
1
+ import { ManagerUtils, MiniMap, QueueSymbol } from "./Utils.js";
2
2
  export class QueueSaver {
3
3
  /**
4
4
  * The queue store manager
@@ -1,4 +1,4 @@
1
- import type { FloatNumber, IntegerNumber } from "./Utils";
1
+ import type { FloatNumber, IntegerNumber } from "./Utils.js";
2
2
  /** The Audio Outputs type */
3
3
  export type AudioOutputs = "mono" | "stereo" | "left" | "right";
4
4
  /** The "active" / "disabled" Player Filters */
@@ -1,10 +1,10 @@
1
- import type { DebugEvents } from "../Constants";
2
- import type { Player } from "../Player";
3
- import type { LavalinkNodeOptions } from "./Node";
4
- import type { DestroyReasonsType, PlayerJson } from "./Player";
5
- import type { ManagerQueueOptions } from "./Queue";
6
- import type { Track, UnresolvedTrack } from "./Track";
7
- import type { GuildShardPayload, SearchPlatform, SponsorBlockChaptersLoaded, SponsorBlockChapterStarted, SponsorBlockSegmentSkipped, SponsorBlockSegmentsLoaded, TrackExceptionEvent, TrackEndEvent, TrackStuckEvent, WebSocketClosedEvent, TrackStartEvent } from "./Utils";
1
+ import type { DebugEvents } from "../Constants.js";
2
+ import type { Player } from "../Player.js";
3
+ import type { LavalinkNodeOptions } from "./Node.js";
4
+ import type { DestroyReasonsType, PlayerJson } from "./Player.js";
5
+ import type { ManagerQueueOptions } from "./Queue.js";
6
+ import type { Track, UnresolvedTrack } from "./Track.js";
7
+ import type { GuildShardPayload, SearchPlatform, SponsorBlockChaptersLoaded, SponsorBlockChapterStarted, SponsorBlockSegmentSkipped, SponsorBlockSegmentsLoaded, TrackExceptionEvent, TrackEndEvent, TrackStuckEvent, WebSocketClosedEvent, TrackStartEvent } from "./Utils.js";
8
8
  /**
9
9
  * The events from the lavalink Manager
10
10
  */
@@ -1,8 +1,8 @@
1
1
  /// <reference types="node" />
2
2
  import type internal from "stream";
3
- import type { LavalinkNode } from "../Node";
4
- import type { DestroyReasonsType } from "./Player";
5
- import type { InvalidLavalinkRestRequest, LavalinkPlayer } from "./Utils";
3
+ import type { LavalinkNode } from "../Node.js";
4
+ import type { DestroyReasonsType } from "./Player.js";
5
+ import type { InvalidLavalinkRestRequest, LavalinkPlayer } from "./Utils.js";
6
6
  /** Ability to manipulate fetch requests */
7
7
  export type ModifyRequest = (options: RequestInit & {
8
8
  path: string;
@@ -1,8 +1,8 @@
1
- import type { DestroyReasons } from "../Constants";
2
- import type { LavalinkNode } from "../Node";
3
- import type { EQBand, FilterData, LavalinkFilterData } from "./Filters";
4
- import type { Track, UnresolvedTrack } from "./Track";
5
- import type { Base64, LavalinkPlayerVoiceOptions } from "./Utils";
1
+ import type { DestroyReasons } from "../Constants.js";
2
+ import type { LavalinkNode } from "../Node.js";
3
+ import type { EQBand, FilterData, LavalinkFilterData } from "./Filters.js";
4
+ import type { Track, UnresolvedTrack } from "./Track.js";
5
+ import type { Base64, LavalinkPlayerVoiceOptions } from "./Utils.js";
6
6
  export type DestroyReasonsType = keyof typeof DestroyReasons | string;
7
7
  export interface PlayerJson {
8
8
  /** Guild Id where the player was playing in */
@@ -1,4 +1,4 @@
1
- import type { Track, UnresolvedTrack } from "./Track";
1
+ import type { Track, UnresolvedTrack } from "./Track.js";
2
2
  export interface StoredQueue {
3
3
  current: Track | null;
4
4
  previous: Track[];
@@ -1,6 +1,6 @@
1
- import type { Player } from "../Player";
2
- import type { anyObject } from "./Player";
3
- import type { Base64 } from "./Utils";
1
+ import type { Player } from "../Player.js";
2
+ import type { anyObject } from "./Player.js";
3
+ import type { Base64 } from "./Utils.js";
4
4
  /** Sourcenames provided by lavalink server */
5
5
  export type LavalinkSourceNames = "youtube" | "youtubemusic" | "soundcloud" | "bandcamp" | "twitch";
6
6
  /** Source Names provided by lava src plugin */
@@ -1,8 +1,8 @@
1
- import type { MiniMap } from "../Utils";
2
- import type { LavalinkFilterData } from "./Filters";
3
- import type { NodeStats } from "./Node";
4
- import type { LavalinkPlayOptions } from "./Player";
5
- import type { LavalinkTrack, PluginInfo, Track, UnresolvedTrack } from "./Track";
1
+ import type { MiniMap } from "../Utils.js";
2
+ import type { LavalinkFilterData } from "./Filters.js";
3
+ import type { NodeStats } from "./Node.js";
4
+ import type { LavalinkPlayOptions } from "./Player.js";
5
+ import type { LavalinkTrack, PluginInfo, Track, UnresolvedTrack } from "./Track.js";
6
6
  /** Helper for generating Opaque types. */
7
7
  export type Opaque<T, K> = T & {
8
8
  __opaque__: K;
@@ -1,9 +1,9 @@
1
- import type { LavalinkNodeOptions } from "./Types/Node";
2
- import type { LavalinkSearchPlatform, LavaSearchQuery, MiniMapConstructor, SearchPlatform, SearchQuery } from "./Types/Utils";
3
- import type { LavalinkManager } from "./LavalinkManager";
4
- import type { LavalinkNode } from "./Node";
5
- import type { Player } from "./Player";
6
- import type { LavalinkTrack, Track, UnresolvedQuery, UnresolvedTrack } from "./Types/Track";
1
+ import type { LavalinkNodeOptions } from "./Types/Node.js";
2
+ import type { LavalinkSearchPlatform, LavaSearchQuery, MiniMapConstructor, SearchPlatform, SearchQuery } from "./Types/Utils.js";
3
+ import type { LavalinkManager } from "./LavalinkManager.js";
4
+ import type { LavalinkNode } from "./Node.js";
5
+ import type { Player } from "./Player.js";
6
+ import type { LavalinkTrack, Track, UnresolvedQuery, UnresolvedTrack } from "./Types/Track.js";
7
7
  export declare const TrackSymbol: unique symbol;
8
8
  export declare const UnresolvedTrackSymbol: unique symbol;
9
9
  export declare const QueueSymbol: unique symbol;
@@ -1,7 +1,7 @@
1
1
  import { URL } from "node:url";
2
2
  import { isRegExp } from "node:util/types";
3
- import { DebugEvents } from "./Constants";
4
- import { DefaultSources, LavalinkPlugins, SourceLinksRegexes } from "./LavalinkManagerStatics";
3
+ import { DebugEvents } from "./Constants.js";
4
+ import { DefaultSources, LavalinkPlugins, SourceLinksRegexes } from "./LavalinkManagerStatics.js";
5
5
  export const TrackSymbol = Symbol("LC-Track");
6
6
  export const UnresolvedTrackSymbol = Symbol("LC-Track-Unresolved");
7
7
  export const QueueSymbol = Symbol("LC-Queue");
@@ -421,11 +421,27 @@ export async function queueTrackEnd(player) {
421
421
  player.queue.tracks.push(player.queue.current);
422
422
  // change the current Track to the next upcoming one
423
423
  const nextSong = player.queue.tracks.shift();
424
- if (player.LavalinkManager.utils.isUnresolvedTrack(nextSong))
425
- await nextSong.resolve(player);
426
- player.queue.current = nextSong || null;
427
- // save it in the DB
428
- await player.queue.utils.save();
424
+ try {
425
+ if (player.LavalinkManager.utils.isUnresolvedTrack(nextSong))
426
+ await nextSong.resolve(player);
427
+ player.queue.current = nextSong || null;
428
+ // save it in the DB
429
+ await player.queue.utils.save();
430
+ }
431
+ catch (error) {
432
+ if (player.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
433
+ player.LavalinkManager.emit("debug", DebugEvents.PlayerPlayUnresolvedTrackFailed, {
434
+ state: "error",
435
+ error: error,
436
+ message: `queueTrackEnd Util was called, tried to resolve the next track, but failed to find the closest matching song`,
437
+ functionLayer: "Player > play() > resolve currentTrack",
438
+ });
439
+ }
440
+ player.LavalinkManager.emit("trackError", player, player.queue.current, error);
441
+ // try to play the next track if possible
442
+ if (player.LavalinkManager.options?.autoSkipOnResolveError === true && player.queue.tracks[0])
443
+ return queueTrackEnd(player);
444
+ }
429
445
  // return the new current Track
430
446
  return player.queue.current;
431
447
  }
@@ -3,6 +3,7 @@ export declare enum DebugEvents {
3
3
  SetSponsorBlock = "SetSponsorBlock",
4
4
  DeleteSponsorBlock = "DeleteSponsorBlock",
5
5
  TrackEndReplaced = "TrackEndReplaced",
6
+ AutoplayExecution = "AutoplayExecution",
6
7
  AutoplayNoSongsAdded = "AutoplayNoSongsAdded",
7
8
  AutoplayThresholdSpamLimiter = "AutoplayThresholdSpamLimiter",
8
9
  TriggerQueueEmptyInterval = "TriggerQueueEmptyInterval",
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { EventEmitter } from "stream";
2
+ import { EventEmitter } from "events";
3
3
  import { LavalinkNode } from "./Node";
4
4
  import { MiniMap } from "./Utils";
5
5
  import type { LavalinkNodeIdentifier, LavalinkNodeOptions, NodeManagerEvents } from "./Types/Node";
package/package.json CHANGED
@@ -1,21 +1,27 @@
1
1
  {
2
2
  "name": "lavalink-client",
3
- "version": "2.3.3",
3
+ "version": "2.3.5",
4
4
  "description": "Easy, flexible and feature-rich lavalink@v4 Client. Both for Beginners and Proficients.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
7
7
  "types": "dist/types/index.d.js",
8
8
  "scripts": {
9
9
  "build": "npm run build:cjs && npm run build:esm && npm run build:types",
10
- "build:cjs": "node tools/cleanup cjs && tsc -p config/tsconfig.cjs.json",
11
- "build:esm": "node tools/cleanup esm && tsc -p config/tsconfig.esm.json",
12
- "build:types": "node tools/cleanup types && tsc -p config/tsconfig.types.json",
10
+ "build:cjs": "node tools/cleanup cjs && tsc -p config/tsconfig.cjs.json && tsc-alias -p config/tsconfig.cjs.json && node tools/fixup cjs",
11
+ "build:esm": "node tools/cleanup esm && tsc -p config/tsconfig.esm.json && tsc-alias -p config/tsconfig.esm.json && node tools/fixup esm",
12
+ "build:types": "node tools/cleanup types && tsc -p config/tsconfig.types.json && tsc-alias -p config/tsconfig.types.json",
13
13
  "clean": "node tools/cleanup",
14
14
  "lint": "eslint .",
15
15
  "lint:fix": "npm run lint -- --fix",
16
16
  "test": "node -v",
17
17
  "docs": "npx typedoc"
18
18
  },
19
+ "exports": {
20
+ "require": "./dist/cjs/index.js",
21
+ "import": "./dist/esm/index.js",
22
+ "types": "./dist/types/index.d.js",
23
+ "default": "./dist/cjs/index.js"
24
+ },
19
25
  "publishConfig": {
20
26
  "access": "public"
21
27
  },
@@ -52,7 +58,7 @@
52
58
  "@typescript-eslint/eslint-plugin": "^6.4.0",
53
59
  "@typescript-eslint/parser": "^6.4.0",
54
60
  "eslint": "^8.47.0",
55
- "ts-loader": "^9.4.4",
61
+ "tsc-alias": "^1.8.10",
56
62
  "typedoc": "^0.25.4",
57
63
  "typedoc-theme-hierarchy": "^4.1.2",
58
64
  "typescript": "^5.1.6"
@@ -62,6 +68,7 @@
62
68
  "ws": "^8.13.0"
63
69
  },
64
70
  "engines": {
65
- "node": ">=18.0.0"
71
+ "node": ">=18.0.0",
72
+ "bun": ">=1.0.0"
66
73
  }
67
74
  }