Skip to content
This repository has been archived by the owner on Nov 13, 2022. It is now read-only.

Commit

Permalink
Merge pull request #91 from MeLike2D/master
Browse files Browse the repository at this point in the history
  • Loading branch information
acollierr17 authored Apr 1, 2021
2 parents 788eef9 + 9afaa94 commit f0bd285
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 46 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ node_modules
dist
.idea
typings
test

# files
package-lock.json
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
"repository": "MenuDocs/erela.js",
"bugs": "https://github.com/MenuDocs/erela.js",
"devDependencies": {
"@types/axios": "^0.14.0",
"@types/node": "^14.6.0",
"@types/ws": "^6.0.4",
"@typescript-eslint/eslint-plugin": "^3.10.1",
Expand All @@ -48,7 +47,7 @@
},
"dependencies": {
"@discordjs/collection": "^0.1.6",
"axios": "^0.21.0",
"petitio": "^1.1.0",
"ws": "^7.3.1"
},
"eslintConfig": {
Expand Down
73 changes: 29 additions & 44 deletions src/structures/Manager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* eslint-disable no-async-promise-executor */
import Collection from "@discordjs/collection";
import Axios from "axios";
import { EventEmitter } from "events";
import { Node, NodeOptions } from "./Node";
import { Player, PlayerOptions, Track, UnresolvedTrack } from "./Player";
Expand Down Expand Up @@ -61,6 +60,12 @@ function check(options: ManagerOptions) {
!Array.isArray(options.trackPartial)
)
throw new TypeError('Manager option "trackPartial" must be a string array.');

if (
typeof options.clientName !== "undefined" &&
typeof options.clientName !== "string"
)
throw new TypeError('Manager option "clientName" must be a string.');
}

export interface Manager {
Expand Down Expand Up @@ -251,6 +256,7 @@ export class Manager extends EventEmitter {
nodes: [{ identifier: "default", host: "localhost" }],
shards: 1,
autoPlay: true,
clientName: "erela.js",
...options,
};

Expand Down Expand Up @@ -316,39 +322,30 @@ export class Manager extends EventEmitter {
search = `${source}search:${search}`;
}

const url = `http${node.options.secure ? "s" : ""}://${
node.options.host
}:${node.options.port}/loadtracks`;

const res = await Axios.get<LavalinkResult>(url, {
headers: { Authorization: node.options.password },
params: { identifier: search },
timeout: 10000,
timeoutErrorMessage: `Node ${node.options.identifier} search timed out.`,
}).catch((err) => {
return reject(err);
});

node.calls++;
const res = await node.makeRequest<LavalinkResult>(`/loadtracks?identifier=${encodeURIComponent(search)}`, r => {
if (node.options.requestTimeout) {
r.timeout(node.options.requestTimeout)
}
}).catch(err => reject(err));

if (!res || !res.data) {
if (!res) {
return reject(new Error("Query not found."));
}

const result: SearchResult = {
loadType: res.data.loadType,
exception: res.data.exception ?? null,
tracks: res.data.tracks.map((track: TrackData) =>
loadType: res.loadType,
exception: res.exception ?? null,
tracks: res.tracks.map((track: TrackData) =>
TrackUtils.build(track, requester)
),
};

if (result.loadType === "PLAYLIST_LOADED") {
result.playlist = {
name: res.data.playlistInfo.name,
selectedTrack: res.data.playlistInfo.selectedTrack === -1 ? null :
name: res.playlistInfo.name,
selectedTrack: res.playlistInfo.selectedTrack === -1 ? null :
TrackUtils.build(
res.data.tracks[res.data.playlistInfo.selectedTrack],
res.tracks[res.playlistInfo.selectedTrack],
requester
),
duration: result.tracks
Expand All @@ -368,39 +365,26 @@ export class Manager extends EventEmitter {
return new Promise(async (resolve, reject) => {
const node = this.nodes.first();
if (!node) throw new Error("No available nodes.");
const url = `http${node.options.secure ? "s" : ""}://${
node.options.host
}:${node.options.port}/decodetracks`;

const res = await Axios.post<TrackData[]>(url, tracks, {
headers: { Authorization: node.options.password },
}).catch((err) => {
return reject(err);
});

node.calls++;
const res = await node.makeRequest<TrackData[]>(`/decodetracks`, r => r
.body(tracks, "json"))
.catch(err => reject(err));

if (!res || !res.data) {
if (!res) {
return reject(new Error("No data returned from query."));
}

return resolve(res.data);
return resolve(res);
});
}

/**
* Decodes the base64 encoded track and returns a TrackData.
* @param track
*/
public decodeTrack(track: string): Promise<TrackData> {
return new Promise(async (resolve, reject) => {
try {
const res = await this.decodeTracks([track]);
return resolve(res[0]);
} catch (e) {
return reject(e);
}
});
public async decodeTrack(track: string): Promise<TrackData> {
const res = await this.decodeTracks([ track ]);
return res[0];
}

/**
Expand Down Expand Up @@ -505,6 +489,8 @@ export interface ManagerOptions {
nodes?: NodeOptions[];
/** The client ID to use. */
clientId?: string;
/** Value to use for the `Client-Name` header. */
clientName?: string;
/** The shard count. */
shards?: number;
/** A array of plugins to use. */
Expand All @@ -513,7 +499,6 @@ export interface ManagerOptions {
autoPlay?: boolean;
/** An array of track properties to keep. `track` will always be present. */
trackPartial?: string[];

/**
* Function to send data to the websocket.
* @param id
Expand Down
35 changes: 35 additions & 0 deletions src/structures/Node.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable no-case-declarations */
import WebSocket from "ws";
import fetch from "petitio";
import { Manager } from "./Manager";
import { Player, Track, UnresolvedTrack } from "./Player";
import {
Expand All @@ -13,6 +14,8 @@ import {
WebSocketClosedEvent,
} from "./Utils";

import type { PetitioRequest } from "petitio/dist/lib/PetitioRequest";

function check(options: NodeOptions) {
if (!options) throw new TypeError("NodeOptions must not be empty.");

Expand Down Expand Up @@ -58,6 +61,12 @@ function check(options: NodeOptions) {
typeof options.retryDelay !== "number"
)
throw new TypeError('Node option "retryDelay" must be a number.');

if (
typeof options.requestTimeout !== "undefined" &&
typeof options.requestTimeout !== "number"
)
throw new TypeError('Node option "requestTimeout" must be a number.');
}

export class Node {
Expand Down Expand Up @@ -141,6 +150,7 @@ export class Node {
Authorization: this.options.password,
"Num-Shards": String(this.manager.options.shards),
"User-Id": this.manager.options.clientId,
"Client-Name": this.manager.options.clientName,
};

this.socket = new WebSocket(
Expand Down Expand Up @@ -173,6 +183,26 @@ export class Node {
this.manager.destroyNode(this.options.identifier);
}

/**
* Makes an API call to the Node
* @param endpoint The endpoint that we will make the call to
* @param modify Used to modify the request before being sent
* @returns The returned data
*/
public async makeRequest<T>(endpoint: string, modify?: ModifyRequest): Promise<T> {
endpoint = endpoint.replace(/^\//gm, "");

const request = fetch(`http${this.options.secure ? "s" : ""}://${this.options.host}:${this.options.port}/${endpoint}`)
.header("Authorization", this.options.password);

if (modify) {
await modify(request);
}

this.calls++;
return await request.json();
}

/**
* Sends data to the Node.
* @param data
Expand Down Expand Up @@ -375,6 +405,9 @@ export class Node {
}
}

/** Modifies any outgoing REST requests. */
export type ModifyRequest = (request: PetitioRequest) => any | Promise<any>;

export interface NodeOptions {
/** The host for the node. */
host: string;
Expand All @@ -390,6 +423,8 @@ export interface NodeOptions {
retryAmount?: number;
/** The retryDelay for the node. */
retryDelay?: number;
/** The timeout used for api calls */
requestTimeout?: number;
}

export interface NodeStats {
Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"declaration": true,
"outDir": "./dist",
"rootDir": "./src",
"skipLibCheck": true,

/* Strict Type-Checking Options */
// "strict": true,
Expand Down

0 comments on commit f0bd285

Please sign in to comment.