lavalink-client 1.2.4 → 1.2.6

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.
@@ -16,7 +16,7 @@ export interface BotClientOptions {
16
16
  /** Bot Client Username */
17
17
  username?: string;
18
18
  /** So users can pass entire objects / classes */
19
- [x: string | number | symbol | undefined]: unknown;
19
+ [x: string | number | symbol]: unknown;
20
20
  }
21
21
  export interface ManagerPlayerOptions {
22
22
  /** If the Lavalink Volume should be decremented by x number */
@@ -93,7 +93,7 @@ class LavalinkManager extends events_1.EventEmitter {
93
93
  this.utils = new Utils_1.ManagerUtils(this);
94
94
  // use the validators
95
95
  this.applyOptions(options);
96
- this.validateOptions(options);
96
+ this.validateOptions(this.options);
97
97
  // create classes
98
98
  this.nodeManager = new NodeManager_1.NodeManager(this);
99
99
  }
@@ -130,6 +130,7 @@ export declare class LavalinkNode {
130
130
  * @param manager
131
131
  */
132
132
  constructor(options: LavalinkNodeOptions, manager: NodeManager);
133
+ private rawRequest;
133
134
  /**
134
135
  * Makes an API call to the Node
135
136
  * @param endpoint The endpoint that we will make the call to
@@ -138,7 +139,7 @@ export declare class LavalinkNode {
138
139
  */
139
140
  request(endpoint: string, modify?: ModifyRequest, parseAsText?: boolean): Promise<unknown>;
140
141
  search(query: SearchQuery, requestUser: unknown): Promise<SearchResult>;
141
- lavaSearch(query: LavaSearchQuery, requestUser: unknown): Promise<SearchResult | LavaSearchResponse>;
142
+ lavaSearch(query: LavaSearchQuery, requestUser: unknown, throwOnEmpty?: boolean): Promise<SearchResult | LavaSearchResponse>;
142
143
  /**
143
144
  * Update the Player State on the Lavalink Server
144
145
  * @param data
@@ -70,13 +70,7 @@ class LavalinkNode {
70
70
  this.options.regions = (this.options.regions || []).map(a => a.toLowerCase());
71
71
  Object.defineProperty(this, Utils_1.NodeSymbol, { configurable: true, value: true });
72
72
  }
73
- /**
74
- * Makes an API call to the Node
75
- * @param endpoint The endpoint that we will make the call to
76
- * @param modify Used to modify the request before being sent
77
- * @returns The returned data
78
- */
79
- async request(endpoint, modify, parseAsText = false) {
73
+ async rawRequest(endpoint, modify) {
80
74
  const options = {
81
75
  path: `/${this.version}/${endpoint.replace(/^\//gm, "")}`,
82
76
  method: "GET",
@@ -91,15 +85,25 @@ class LavalinkNode {
91
85
  options.path = url.pathname + url.search;
92
86
  const request = await this.rest.request(options);
93
87
  this.calls++;
88
+ return { request, options };
89
+ }
90
+ /**
91
+ * Makes an API call to the Node
92
+ * @param endpoint The endpoint that we will make the call to
93
+ * @param modify Used to modify the request before being sent
94
+ * @returns The returned data
95
+ */
96
+ async request(endpoint, modify, parseAsText = false) {
97
+ const { request, options } = await this.rawRequest(endpoint, modify);
94
98
  if (options.method === "DELETE")
95
99
  return;
96
100
  if (request.statusCode === 404)
97
- throw new Error(`Node Request resulted into an error, request-URL: ${url} | headers: ${JSON.stringify(request.headers)}`);
101
+ throw new Error(`Node Request resulted into an error, request-PATH: ${options.path} | headers: ${JSON.stringify(request.headers)}`);
98
102
  return parseAsText ? await request.body.text() : await request.body.json();
99
103
  }
100
104
  async search(query, requestUser) {
101
105
  const Query = this.NodeManager.LavalinkManager.utils.transformQuery(query);
102
- this.NodeManager.LavalinkManager.utils.validateQueryString(this, Query.query);
106
+ this.NodeManager.LavalinkManager.utils.validateQueryString(this, Query.query, Query.source);
103
107
  if (Query.source)
104
108
  this.NodeManager.LavalinkManager.utils.validateSourceString(this, Query.source);
105
109
  if (["bcsearch", "bandcamp"].includes(Query.source)) {
@@ -130,7 +134,7 @@ class LavalinkNode {
130
134
  tracks: (resTracks.length ? resTracks.map(t => this.NodeManager.LavalinkManager.utils.buildTrack(t, requestUser)) : [])
131
135
  };
132
136
  }
133
- async lavaSearch(query, requestUser) {
137
+ async lavaSearch(query, requestUser, throwOnEmpty = false) {
134
138
  const Query = this.NodeManager.LavalinkManager.utils.transformLavaSearchQuery(query);
135
139
  if (Query.source)
136
140
  this.NodeManager.LavalinkManager.utils.validateSourceString(this, Query.source);
@@ -142,7 +146,10 @@ class LavalinkNode {
142
146
  throw new RangeError(`there is no lavasearch-plugin available in the lavalink node: ${this.id}`);
143
147
  if (!this.info.plugins.find(v => v.name === "lavasrc-plugin"))
144
148
  throw new RangeError(`there is no lavasrc-plugin available in the lavalink node: ${this.id}`);
145
- const res = await this.request(`/loadsearch?query=${Query.source ? `${Query.source}:` : ""}${encodeURIComponent(Query.query)}${Query.types?.length ? `&types=${Query.types.join(",")}` : ""}`);
149
+ const { request } = await this.rawRequest(`/loadsearch?query=${Query.source ? `${Query.source}:` : ""}${encodeURIComponent(Query.query)}${Query.types?.length ? `&types=${Query.types.join(",")}` : ""}`);
150
+ if (throwOnEmpty === true)
151
+ throw new Error("Nothing found");
152
+ const res = (request.statusCode === 204 ? {} : await request.body.json());
146
153
  return {
147
154
  tracks: res.tracks?.map(v => this.NodeManager.LavalinkManager.utils.buildTrack(v, requestUser)) || [],
148
155
  albums: res.albums?.map(v => ({ info: v.info, pluginInfo: v?.plugin || v.pluginInfo, tracks: v.tracks.map(v => this.NodeManager.LavalinkManager.utils.buildTrack(v, requestUser)) })) || [],
@@ -100,7 +100,7 @@ export declare class ManagerUtils {
100
100
  */
101
101
  isUnresolvedTrackQuery(data: UnresolvedQuery | any): boolean;
102
102
  getClosestTrack(data: UnresolvedTrack, player: Player): Promise<Track | undefined>;
103
- validateQueryString(node: LavalinkNode, queryString: string): void;
103
+ validateQueryString(node: LavalinkNode, queryString: string, sourceString?: LavalinkSearchPlatform): void;
104
104
  transformQuery(query: SearchQuery): {
105
105
  query: string;
106
106
  source: any;
@@ -180,15 +180,16 @@ class ManagerUtils {
180
180
  async getClosestTrack(data, player) {
181
181
  return getClosestTrack(data, player);
182
182
  }
183
- validateQueryString(node, queryString) {
183
+ validateQueryString(node, queryString, sourceString) {
184
184
  if (!node.info)
185
185
  throw new Error("No Lavalink Node was provided");
186
186
  if (!node.info.sourceManagers?.length)
187
187
  throw new Error("Lavalink Node, has no sourceManagers enabled");
188
- // checks for blacklisted links / domains / queries
189
- if (this.LavalinkManager.options?.linksBlacklist?.length > 0 && this.LavalinkManager.options?.linksBlacklist.some(v => (typeof v === "string" && (queryString.toLowerCase().includes(v.toLowerCase()) || v.toLowerCase().includes(queryString.toLowerCase()))) || (0, types_1.isRegExp)(v) && v.test(queryString))) {
190
- throw new Error(`Query string contains a link / word which is blacklisted.`);
191
- }
188
+ if (sourceString === "speak" && queryString.length > 100)
189
+ // checks for blacklisted links / domains / queries
190
+ if (this.LavalinkManager.options?.linksBlacklist?.length > 0 && this.LavalinkManager.options?.linksBlacklist.some(v => (typeof v === "string" && (queryString.toLowerCase().includes(v.toLowerCase()) || v.toLowerCase().includes(queryString.toLowerCase()))) || (0, types_1.isRegExp)(v) && v.test(queryString))) {
191
+ throw new Error(`Query string contains a link / word which is blacklisted.`);
192
+ }
192
193
  if (!/^https?:\/\//.test(queryString))
193
194
  return;
194
195
  else if (this.LavalinkManager.options?.linksAllowed === false)
@@ -16,7 +16,7 @@ export interface BotClientOptions {
16
16
  /** Bot Client Username */
17
17
  username?: string;
18
18
  /** So users can pass entire objects / classes */
19
- [x: string | number | symbol | undefined]: unknown;
19
+ [x: string | number | symbol]: unknown;
20
20
  }
21
21
  export interface ManagerPlayerOptions {
22
22
  /** If the Lavalink Volume should be decremented by x number */
@@ -90,7 +90,7 @@ export class LavalinkManager extends EventEmitter {
90
90
  this.utils = new ManagerUtils(this);
91
91
  // use the validators
92
92
  this.applyOptions(options);
93
- this.validateOptions(options);
93
+ this.validateOptions(this.options);
94
94
  // create classes
95
95
  this.nodeManager = new NodeManager(this);
96
96
  }
@@ -130,6 +130,7 @@ export declare class LavalinkNode {
130
130
  * @param manager
131
131
  */
132
132
  constructor(options: LavalinkNodeOptions, manager: NodeManager);
133
+ private rawRequest;
133
134
  /**
134
135
  * Makes an API call to the Node
135
136
  * @param endpoint The endpoint that we will make the call to
@@ -138,7 +139,7 @@ export declare class LavalinkNode {
138
139
  */
139
140
  request(endpoint: string, modify?: ModifyRequest, parseAsText?: boolean): Promise<unknown>;
140
141
  search(query: SearchQuery, requestUser: unknown): Promise<SearchResult>;
141
- lavaSearch(query: LavaSearchQuery, requestUser: unknown): Promise<SearchResult | LavaSearchResponse>;
142
+ lavaSearch(query: LavaSearchQuery, requestUser: unknown, throwOnEmpty?: boolean): Promise<SearchResult | LavaSearchResponse>;
142
143
  /**
143
144
  * Update the Player State on the Lavalink Server
144
145
  * @param data
@@ -66,13 +66,7 @@ export class LavalinkNode {
66
66
  this.options.regions = (this.options.regions || []).map(a => a.toLowerCase());
67
67
  Object.defineProperty(this, NodeSymbol, { configurable: true, value: true });
68
68
  }
69
- /**
70
- * Makes an API call to the Node
71
- * @param endpoint The endpoint that we will make the call to
72
- * @param modify Used to modify the request before being sent
73
- * @returns The returned data
74
- */
75
- async request(endpoint, modify, parseAsText = false) {
69
+ async rawRequest(endpoint, modify) {
76
70
  const options = {
77
71
  path: `/${this.version}/${endpoint.replace(/^\//gm, "")}`,
78
72
  method: "GET",
@@ -87,15 +81,25 @@ export class LavalinkNode {
87
81
  options.path = url.pathname + url.search;
88
82
  const request = await this.rest.request(options);
89
83
  this.calls++;
84
+ return { request, options };
85
+ }
86
+ /**
87
+ * Makes an API call to the Node
88
+ * @param endpoint The endpoint that we will make the call to
89
+ * @param modify Used to modify the request before being sent
90
+ * @returns The returned data
91
+ */
92
+ async request(endpoint, modify, parseAsText = false) {
93
+ const { request, options } = await this.rawRequest(endpoint, modify);
90
94
  if (options.method === "DELETE")
91
95
  return;
92
96
  if (request.statusCode === 404)
93
- throw new Error(`Node Request resulted into an error, request-URL: ${url} | headers: ${JSON.stringify(request.headers)}`);
97
+ throw new Error(`Node Request resulted into an error, request-PATH: ${options.path} | headers: ${JSON.stringify(request.headers)}`);
94
98
  return parseAsText ? await request.body.text() : await request.body.json();
95
99
  }
96
100
  async search(query, requestUser) {
97
101
  const Query = this.NodeManager.LavalinkManager.utils.transformQuery(query);
98
- this.NodeManager.LavalinkManager.utils.validateQueryString(this, Query.query);
102
+ this.NodeManager.LavalinkManager.utils.validateQueryString(this, Query.query, Query.source);
99
103
  if (Query.source)
100
104
  this.NodeManager.LavalinkManager.utils.validateSourceString(this, Query.source);
101
105
  if (["bcsearch", "bandcamp"].includes(Query.source)) {
@@ -126,7 +130,7 @@ export class LavalinkNode {
126
130
  tracks: (resTracks.length ? resTracks.map(t => this.NodeManager.LavalinkManager.utils.buildTrack(t, requestUser)) : [])
127
131
  };
128
132
  }
129
- async lavaSearch(query, requestUser) {
133
+ async lavaSearch(query, requestUser, throwOnEmpty = false) {
130
134
  const Query = this.NodeManager.LavalinkManager.utils.transformLavaSearchQuery(query);
131
135
  if (Query.source)
132
136
  this.NodeManager.LavalinkManager.utils.validateSourceString(this, Query.source);
@@ -138,7 +142,10 @@ export class LavalinkNode {
138
142
  throw new RangeError(`there is no lavasearch-plugin available in the lavalink node: ${this.id}`);
139
143
  if (!this.info.plugins.find(v => v.name === "lavasrc-plugin"))
140
144
  throw new RangeError(`there is no lavasrc-plugin available in the lavalink node: ${this.id}`);
141
- const res = await this.request(`/loadsearch?query=${Query.source ? `${Query.source}:` : ""}${encodeURIComponent(Query.query)}${Query.types?.length ? `&types=${Query.types.join(",")}` : ""}`);
145
+ const { request } = await this.rawRequest(`/loadsearch?query=${Query.source ? `${Query.source}:` : ""}${encodeURIComponent(Query.query)}${Query.types?.length ? `&types=${Query.types.join(",")}` : ""}`);
146
+ if (throwOnEmpty === true)
147
+ throw new Error("Nothing found");
148
+ const res = (request.statusCode === 204 ? {} : await request.body.json());
142
149
  return {
143
150
  tracks: res.tracks?.map(v => this.NodeManager.LavalinkManager.utils.buildTrack(v, requestUser)) || [],
144
151
  albums: res.albums?.map(v => ({ info: v.info, pluginInfo: v?.plugin || v.pluginInfo, tracks: v.tracks.map(v => this.NodeManager.LavalinkManager.utils.buildTrack(v, requestUser)) })) || [],
@@ -100,7 +100,7 @@ export declare class ManagerUtils {
100
100
  */
101
101
  isUnresolvedTrackQuery(data: UnresolvedQuery | any): boolean;
102
102
  getClosestTrack(data: UnresolvedTrack, player: Player): Promise<Track | undefined>;
103
- validateQueryString(node: LavalinkNode, queryString: string): void;
103
+ validateQueryString(node: LavalinkNode, queryString: string, sourceString?: LavalinkSearchPlatform): void;
104
104
  transformQuery(query: SearchQuery): {
105
105
  query: string;
106
106
  source: any;
@@ -176,15 +176,16 @@ export class ManagerUtils {
176
176
  async getClosestTrack(data, player) {
177
177
  return getClosestTrack(data, player);
178
178
  }
179
- validateQueryString(node, queryString) {
179
+ validateQueryString(node, queryString, sourceString) {
180
180
  if (!node.info)
181
181
  throw new Error("No Lavalink Node was provided");
182
182
  if (!node.info.sourceManagers?.length)
183
183
  throw new Error("Lavalink Node, has no sourceManagers enabled");
184
- // checks for blacklisted links / domains / queries
185
- if (this.LavalinkManager.options?.linksBlacklist?.length > 0 && this.LavalinkManager.options?.linksBlacklist.some(v => (typeof v === "string" && (queryString.toLowerCase().includes(v.toLowerCase()) || v.toLowerCase().includes(queryString.toLowerCase()))) || isRegExp(v) && v.test(queryString))) {
186
- throw new Error(`Query string contains a link / word which is blacklisted.`);
187
- }
184
+ if (sourceString === "speak" && queryString.length > 100)
185
+ // checks for blacklisted links / domains / queries
186
+ if (this.LavalinkManager.options?.linksBlacklist?.length > 0 && this.LavalinkManager.options?.linksBlacklist.some(v => (typeof v === "string" && (queryString.toLowerCase().includes(v.toLowerCase()) || v.toLowerCase().includes(queryString.toLowerCase()))) || isRegExp(v) && v.test(queryString))) {
187
+ throw new Error(`Query string contains a link / word which is blacklisted.`);
188
+ }
188
189
  if (!/^https?:\/\//.test(queryString))
189
190
  return;
190
191
  else if (this.LavalinkManager.options?.linksAllowed === false)
@@ -16,7 +16,7 @@ export interface BotClientOptions {
16
16
  /** Bot Client Username */
17
17
  username?: string;
18
18
  /** So users can pass entire objects / classes */
19
- [x: string | number | symbol | undefined]: unknown;
19
+ [x: string | number | symbol]: unknown;
20
20
  }
21
21
  export interface ManagerPlayerOptions {
22
22
  /** If the Lavalink Volume should be decremented by x number */
@@ -130,6 +130,7 @@ export declare class LavalinkNode {
130
130
  * @param manager
131
131
  */
132
132
  constructor(options: LavalinkNodeOptions, manager: NodeManager);
133
+ private rawRequest;
133
134
  /**
134
135
  * Makes an API call to the Node
135
136
  * @param endpoint The endpoint that we will make the call to
@@ -138,7 +139,7 @@ export declare class LavalinkNode {
138
139
  */
139
140
  request(endpoint: string, modify?: ModifyRequest, parseAsText?: boolean): Promise<unknown>;
140
141
  search(query: SearchQuery, requestUser: unknown): Promise<SearchResult>;
141
- lavaSearch(query: LavaSearchQuery, requestUser: unknown): Promise<SearchResult | LavaSearchResponse>;
142
+ lavaSearch(query: LavaSearchQuery, requestUser: unknown, throwOnEmpty?: boolean): Promise<SearchResult | LavaSearchResponse>;
142
143
  /**
143
144
  * Update the Player State on the Lavalink Server
144
145
  * @param data
@@ -100,7 +100,7 @@ export declare class ManagerUtils {
100
100
  */
101
101
  isUnresolvedTrackQuery(data: UnresolvedQuery | any): boolean;
102
102
  getClosestTrack(data: UnresolvedTrack, player: Player): Promise<Track | undefined>;
103
- validateQueryString(node: LavalinkNode, queryString: string): void;
103
+ validateQueryString(node: LavalinkNode, queryString: string, sourceString?: LavalinkSearchPlatform): void;
104
104
  transformQuery(query: SearchQuery): {
105
105
  query: string;
106
106
  source: any;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lavalink-client",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
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",