diff --git a/package-lock.json b/package-lock.json index ef42d8c0..e8efdf5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,16 @@ { "name": "magmastream", - "version": "2.0.0-beta", + "version": "2.0.2-beta", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "magmastream", - "version": "2.0.0-beta", + "version": "2.0.2-beta", "license": "Apache-2.0", "dependencies": { "@discordjs/collection": "^1.5.1", + "axios": "^1.4.0", "events": "^3.3.0", "lodash": "^4.17.21", "tslib": "^2.4.0", @@ -657,6 +658,11 @@ "node": ">=8" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -669,6 +675,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/axios": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", + "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", @@ -780,6 +796,17 @@ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "9.5.0", "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", @@ -879,6 +906,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -1329,6 +1364,25 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -1338,6 +1392,19 @@ "is-callable": "^1.1.3" } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/from": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", @@ -2120,6 +2187,25 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2472,6 +2558,11 @@ "node": ">= 0.8.0" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/ps-tree": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", diff --git a/package.json b/package.json index a3417fb8..7392f173 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "magmastream", - "version": "2.0.1-beta", + "version": "2.0.2-beta", "description": "A user-friendly Lavalink client designed for NodeJS.", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -28,6 +28,7 @@ }, "dependencies": { "@discordjs/collection": "^1.5.1", + "axios": "^1.4.0", "events": "^3.3.0", "lodash": "^4.17.21", "tslib": "^2.4.0", @@ -81,6 +82,7 @@ "repository": { "url": "https://github.com/Blackfort-Hosting/magmastream/tree/main" }, + "homepage": "https://docs.blackforthosting.com", "author": "Abel Purnwasy", "license": "Apache-2.0" -} \ No newline at end of file +} diff --git a/src/structures/Filters.ts b/src/structures/Filters.ts index c3f9e3ee..cb4bc05c 100644 --- a/src/structures/Filters.ts +++ b/src/structures/Filters.ts @@ -2,16 +2,66 @@ import { Player } from "./Player"; export class Filters { public player: Player; - public volume = 1.0; - public equalizer: Band[] = []; - public vibrato: vibratoOptions = null; - public rotation: rotationOptions = null; - public timescale: timescaleOptions = null; - public karaoke: karaokeOptions = null; - public distortion: distortionOptions = null; + public volume: number; + public equalizer: Band[]; + public vibrato: vibratoOptions; + public rotation: rotationOptions; + public timescale: timescaleOptions; + public karaoke: karaokeOptions; + public distortion: distortionOptions; constructor(player: Player) { this.player = player; + this.volume = 1.0; + this.equalizer = []; + this.vibrato = null; + this.rotation = null; + this.timescale = null; + this.karaoke = null; + this.distortion = null; + } + + private updateFilters(): this { + const { + equalizer, + karaoke, + timescale, + vibrato, + rotation, + volume, + distortion, + } = this; + + this.player.node.rest.updatePlayer({ + guildId: this.player.guild, + data: { + filters: { + volume, + equalizer, + karaoke, + timescale, + vibrato, + rotation, + distortion, + }, + }, + }); + + return this; + } + + private applyFilter( + filter: { + property: keyof Filters; + value: any; + }, + updateFilters: boolean = true + ): this { + this[filter.property] = filter.value; + if (updateFilters) { + this.updateFilters(); + } + return this; } /** @@ -19,28 +69,20 @@ export class Filters { * @param bands - The equalizer bands. */ public setEqualizer(bands?: Band[]): this { - this.equalizer = bands; - this.updateFilters(); - return this; + return this.applyFilter({ property: "equalizer", value: bands }); } - /** - * Applies the 8D filter. - */ + /** Applies the eight dimension audio effect. */ public eightD(): this { return this.setRotation({ rotationHz: 0.2 }); } - /** - * Applies the bass boost filter. - */ + /** Applies the bass boost effect. */ public bassBoost(): this { return this.setEqualizer(bassBoostEqualizer); } - /** - * Applies the nightcore filter. - */ + /** Applies the nightcore effect. */ public nightcore(): this { return this.setTimescale({ speed: 1.1, @@ -49,9 +91,7 @@ export class Filters { }); } - /** - * Applies the slow motion filter. - */ + /** Applies the slow motion audio effect. */ public slowmo(): this { return this.setTimescale({ speed: 0.7, @@ -60,38 +100,27 @@ export class Filters { }); } - /** - * Applies the soft filter. - */ + /** Applies the soft audio effect. */ public soft(): this { return this.setEqualizer(softEqualizer); } - /** - * Applies the TV filter. - */ + /** Applies the television audio effect. */ public tv(): this { return this.setEqualizer(tvEqualizer); } - /** - * Applies the treble bass filter. - */ + /** Applies the treble bass effect. */ public trebleBass(): this { return this.setEqualizer(trebleBassEqualizer); } - /** - * Applies the vaporwave filter. - */ + /** Applies the vaporwave effect. */ public vaporwave(): this { - this.setEqualizer(vaporwaveEqualizer); - return this.setTimescale({ pitch: 0.55 }); + return this.setEqualizer(vaporwaveEqualizer).setTimescale({ pitch: 0.55 }); } - /** - * Applies the distortion filter. - */ + /** Applies the distortion audio effect. */ public distort(): this { return this.setDistortion({ sinOffset: 0, @@ -105,91 +134,37 @@ export class Filters { }); } - /** - * Applies the karaoke options specified by the filter. - */ + /** Applies the karaoke options specified by the filter. */ public setKaraoke(karaoke?: karaokeOptions): this { - this.karaoke = karaoke || null; - this.updateFilters(); - - return this; + return this.applyFilter({ property: "karaoke", value: karaoke }); } - /** - * Applies the timescale options specified by the filter. - */ + /** Applies the timescale options specified by the filter. */ public setTimescale(timescale?: timescaleOptions): this { - this.timescale = timescale || null; - this.updateFilters(); - - return this; + return this.applyFilter({ property: "timescale", value: timescale }); } - /** - * Applies the vibrato options specified by the filter. - */ + /** Applies the vibrato options specified by the filter. */ public setVibrato(vibrato?: vibratoOptions): this { - this.vibrato = vibrato || null; - this.updateFilters(); - return this; + return this.applyFilter({ property: "vibrato", value: vibrato }); } - /** - * Applies the rotation options specified by the filter. - */ + /** Applies the rotation options specified by the filter. */ public setRotation(rotation?: rotationOptions): this { - this.rotation = rotation || null; - this.updateFilters(); - - return this; + return this.applyFilter({ property: "rotation", value: rotation }); } + /** Applies the distortion options specified by the filter. */ public setDistortion(distortion?: distortionOptions): this { - this.distortion = distortion || null; - this.updateFilters(); - - return this; + return this.applyFilter({ property: "distortion", value: distortion }); } - /** - * Clears the filters. - */ + + /** Removes the audio effects. */ public clearFilters(): this { this.player.filters = new Filters(this.player); this.updateFilters(); return this; } - - /** - * Updates the filters. - */ - public updateFilters(): this { - const { - equalizer, - karaoke, - timescale, - vibrato, - rotation, - volume, - distortion, - } = this; - - this.player.node.rest.updatePlayer({ - guildId: this.player.guild, - data: { - filters: { - volume, - equalizer, - karaoke, - timescale, - vibrato, - rotation, - distortion, - }, - }, - }); - - return this; - } } /** Options for adjusting the timescale of audio. */ @@ -239,6 +214,14 @@ interface distortionOptions { scale?: number; } +/** Represents an equalizer band. */ +interface Band { + /** The index of the equalizer band. */ + band: number; + /** The gain value of the equalizer band. */ + gain: number; +} + const bassBoostEqualizer: Band[] = [ { band: 0, gain: 0.2 }, { band: 1, gain: 0.15 }, @@ -324,11 +307,3 @@ const vaporwaveEqualizer: Band[] = [ { band: 12, gain: 0.15 }, { band: 13, gain: 0.15 }, ]; - -/** Represents an equalizer band. */ -interface Band { - /** The index of the equalizer band. */ - band: number; - /** The gain value of the equalizer band. */ - gain: number; -} diff --git a/src/structures/Manager.ts b/src/structures/Manager.ts index 16d4bce1..ba317368 100644 --- a/src/structures/Manager.ts +++ b/src/structures/Manager.ts @@ -378,8 +378,7 @@ export class Manager extends EventEmitter { break; case "track": - const data = res.data as TrackData[]; - searchData = [data]; + searchData = [res.data as TrackData[]]; break; case "playlist": playlistData = res.data as PlaylistRawData; @@ -418,14 +417,9 @@ export class Manager extends EventEmitter { const node = this.nodes.first(); if (!node) throw new Error("No available nodes."); - const res = await node - .makeRequest(`/decodetracks`, (r) => { - r.method = "POST"; - r.body = JSON.stringify(tracks); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - r.headers!["Content-Type"] = "application/json"; - }) - .catch((err) => reject(err)); + const res = (await node.rest + .post("/v4/decodetracks", JSON.stringify(tracks)) + .catch((err) => reject(err))) as TrackData[]; if (!res) { return reject(new Error("No data returned from query.")); diff --git a/src/structures/Node.ts b/src/structures/Node.ts index e30d8aa6..37bafe68 100644 --- a/src/structures/Node.ts +++ b/src/structures/Node.ts @@ -197,56 +197,6 @@ 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( - endpoint: string, - modify?: ModifyRequest - ): Promise { - const options: Dispatcher.RequestOptions = { - path: `/${endpoint.replace(/^\//gm, "")}`, - method: "GET", - headers: { - Authorization: this.options.password, - }, - headersTimeout: this.options.requestTimeout, - }; - - modify?.(options); - - const request = await this.http.request(options); - this.calls++; - - return await request.body.json(); - } - - /** - * Sends data to the Node. - * @param data - * @deprecated - */ - public send(data: unknown): Promise { - return new Promise((resolve, reject) => { - if (!this.connected) return resolve(false); - if (!data) return reject(false); - - const payload = JSON.stringify(data); - - if (!payload?.startsWith("{")) { - return reject(false); - } - - this.socket.send(payload, (error: Error) => { - if (error) reject(error); - else resolve(true); - }); - }); - } - private reconnect(): void { this.reconnectTimeout = setTimeout(() => { if (this.reconnectAttempts >= this.options.retryAmount) { @@ -333,23 +283,35 @@ export class Node { const track = player.queue.current; const type = payload.type; - if (payload.type === "TrackStartEvent") { - this.trackStart(player, track as Track, payload); - } else if (payload.type === "TrackEndEvent") { - if (player?.nowPlayingMessage && !player?.nowPlayingMessage?.deleted) { - player?.nowPlayingMessage?.delete().catch(() => {}); - } + switch (type) { + case "TrackStartEvent": + this.trackStart(player, track as Track, payload); + break; + + case "TrackEndEvent": + if (player?.nowPlayingMessage && !player?.nowPlayingMessage?.deleted) { + player?.nowPlayingMessage?.delete().catch(() => {}); + } + + this.trackEnd(player, track as Track, payload); + break; + + case "TrackStuckEvent": + this.trackStuck(player, track as Track, payload); + break; - this.trackEnd(player, track as Track, payload); - } else if (payload.type === "TrackStuckEvent") { - this.trackStuck(player, track as Track, payload); - } else if (payload.type === "TrackExceptionEvent") { - this.trackError(player, track, payload); - } else if (payload.type === "WebSocketClosedEvent") { - this.socketClosed(player, payload); - } else { - const error = new Error(`Node#event unknown event '${type}'.`); - this.manager.emit("nodeError", this, error); + case "TrackExceptionEvent": + this.trackError(player, track, payload); + break; + + case "WebSocketClosedEvent": + this.socketClosed(player, payload); + break; + + default: + const error = new Error(`Node#event unknown event '${type}'.`); + this.manager.emit("nodeError", this, error); + break; } } @@ -369,7 +331,7 @@ export class Node { payload: TrackEndEvent ): void { // If a track had an error while starting - if (["LOAD_FAILED", "CLEAN_UP"].includes(payload.reason)) { + if (["loadFailed", "cleanup"].includes(payload.reason)) { player.queue.previous = player.queue.current; player.queue.current = player.queue.shift(); @@ -464,9 +426,6 @@ export class Node { } } -/** Modifies any outgoing REST requests. */ -export type ModifyRequest = (options: Dispatcher.RequestOptions) => void; - export interface NodeOptions { /** The host for the node. */ host: string; diff --git a/src/structures/Player.ts b/src/structures/Player.ts index 49fe1eee..af9483cf 100644 --- a/src/structures/Player.ts +++ b/src/structures/Player.ts @@ -586,5 +586,5 @@ export interface NowPlayingMessage { /** The delete function. */ delete: () => Promise; /** The edit function. */ - edit: () => void; + edit: () => Promise; } diff --git a/src/structures/Queue.ts b/src/structures/Queue.ts index 0493fda4..3d8a1d3a 100644 --- a/src/structures/Queue.ts +++ b/src/structures/Queue.ts @@ -8,11 +8,7 @@ export class Queue extends Array { /** The total duration of the queue. */ public get duration(): number { const current = this.current?.duration ?? 0; - return this - .reduce( - (acc: number, cur: Track) => acc + (cur.duration || 0), - current - ); + return this.reduce((acc, cur) => acc + (cur.duration || 0), current); } /** The total size of tracks in the queue including the current track. */ @@ -22,7 +18,7 @@ export class Queue extends Array { /** The size of tracks in the queue. */ public get size(): number { - return this.length + return this.length; } /** The current track */ @@ -45,30 +41,34 @@ export class Queue extends Array { } if (!this.current) { - if (!Array.isArray(track)) { - this.current = track; - return; + if (Array.isArray(track)) { + this.current = track.shift() || null; + this.push(...track); } else { - this.current = (track = [...track]).shift(); - } - } - - if (typeof offset !== "undefined" && typeof offset === "number") { - if (isNaN(offset)) { - throw new RangeError("Offset must be a number."); - } - - if (offset < 0 || offset > this.length) { - throw new RangeError(`Offset must be or between 0 and ${this.length}.`); + this.current = track; } - } - - if (typeof offset === "undefined" && typeof offset !== "number") { - if (track instanceof Array) this.push(...track); - else this.push(track); } else { - if (track instanceof Array) this.splice(offset, 0, ...track); - else this.splice(offset, 0, track); + if (typeof offset !== "undefined" && typeof offset === "number") { + if (isNaN(offset)) { + throw new RangeError("Offset must be a number."); + } + + if (offset < 0 || offset > this.length) { + throw new RangeError(`Offset must be between 0 and ${this.length}.`); + } + + if (Array.isArray(track)) { + this.splice(offset, 0, ...track); + } else { + this.splice(offset, 0, track); + } + } else { + if (Array.isArray(track)) { + this.push(...track); + } else { + this.push(track); + } + } } } @@ -76,7 +76,7 @@ export class Queue extends Array { * Removes a track from the queue. Defaults to the first track, returning the removed track, EXCLUDING THE `current` TRACK. * @param [position=0] */ - public remove(position?: number): Track[]; + public remove(position?: number): (Track | UnresolvedTrack)[]; /** * Removes an amount of tracks using a exclusive start and end exclusive index, returning the removed tracks, EXCLUDING THE `current` TRACK. @@ -84,16 +84,18 @@ export class Queue extends Array { * @param end */ public remove(start: number, end: number): (Track | UnresolvedTrack)[]; - public remove(startOrPosition = 0, end?: number): (Track | UnresolvedTrack)[] { + + public remove( + startOrPosition = 0, + end?: number + ): (Track | UnresolvedTrack)[] { if (typeof end !== "undefined") { - if (isNaN(Number(startOrPosition))) { - throw new RangeError(`Missing "start" parameter.`); - } else if (isNaN(Number(end))) { - throw new RangeError(`Missing "end" parameter.`); - } else if (startOrPosition >= end) { - throw new RangeError("Start can not be bigger than end."); - } else if (startOrPosition >= this.length) { - throw new RangeError(`Start can not be bigger than ${this.length}.`); + if (isNaN(Number(startOrPosition)) || isNaN(Number(end))) { + throw new RangeError(`Missing "start" or "end" parameter.`); + } + + if (startOrPosition >= end || startOrPosition >= this.length) { + throw new RangeError("Invalid start or end values."); } return this.splice(startOrPosition, end - startOrPosition); diff --git a/src/structures/Rest.ts b/src/structures/Rest.ts index 717f92cd..ac60cb33 100644 --- a/src/structures/Rest.ts +++ b/src/structures/Rest.ts @@ -1,5 +1,5 @@ import { Node } from "./Node"; -import { fetch } from "undici"; +import axios, { AxiosRequestConfig } from "axios"; /** Handles the requests sent to the Lavalink REST API. */ export class Rest { @@ -33,94 +33,60 @@ export class Rest { } /** Sends a PATCH request to update player related data. */ - public async updatePlayer(options: playOptions): Promise { - const request = await this.patch( + public updatePlayer(options: playOptions): Promise { + return this.patch( `/v4/sessions/${this.sessionId}/players/${options.guildId}?noReplace=false`, options.data ); - return request; } /** Sends a DELETE request to the server to destroy the player. */ - public async destroyPlayer(guildId: string) { - const request = await this.delete( - `/v4/sessions/${this.sessionId}/players/${guildId}` - ); - return request; + public destroyPlayer(guildId: string): Promise { + return this.delete(`/v4/sessions/${this.sessionId}/players/${guildId}`); } /* Sends a GET request to the specified endpoint and returns the response data. */ - public async get(path: RouteLike): Promise { - try { - const req = await fetch(this.url + path, { - method: "GET", - headers: { - "Content-Type": "application/json", - Authorization: this.password, - }, - }); + private async request( + method: string, + endpoint: RouteLike, + body?: unknown + ): Promise { + const config: AxiosRequestConfig = { + method, + url: this.url + endpoint, + headers: { + "Content-Type": "application/json", + Authorization: this.password, + }, + data: body, + }; - const json = await req.json(); - return json; - } catch (e) { + try { + const response = await axios(config); + return response.data; + } catch { return null; } } + /* Sends a GET request to the specified endpoint and returns the response data. */ + public async get(endpoint: RouteLike): Promise { + return await this.request("GET", endpoint); + } + /* Sends a PATCH request to the specified endpoint and returns the response data. */ public async patch(endpoint: RouteLike, body: unknown): Promise { - try { - const req = await fetch(this.url + endpoint, { - method: "PATCH", - headers: { - "Content-Type": "application/json", - Authorization: this.password, - }, - body: JSON.stringify(body), - }); - - const json = await req.json(); - return json; - } catch (e) { - return null; - } + return await this.request("PATCH", endpoint, body); } /* Sends a POST request to the specified endpoint and returns the response data. */ public async post(endpoint: RouteLike, body: unknown): Promise { - try { - const req = await fetch(this.url + endpoint, { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: this.password, - }, - body: JSON.stringify(body), - }); - - const json = await req.json(); - return json; - } catch (e) { - return null; - } + return await this.request("POST", endpoint, body); } /* Sends a DELETE request to the specified endpoint and returns the response data. */ public async delete(endpoint: RouteLike): Promise { - try { - const req = await fetch(this.url + endpoint, { - method: "DELETE", - headers: { - "Content-Type": "application/json", - Authorization: this.password, - }, - }); - - const json = await req.json(); - return json; - } catch (e) { - return null; - } + return await this.request("DELETE", endpoint); } }