diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3821078..fd30d6c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,11 +11,11 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node: [12, 14] + node: [14, 16, 18] steps: - - uses: actions/checkout@master - - name: Cache node modules - uses: actions/cache@v2 + - uses: actions/checkout@v3 + - name: Cache node_modules + uses: actions/cache@v3 env: cache-name: cache-node-modules with: @@ -25,12 +25,13 @@ jobs: ${{ runner.os }}-build-${{ env.cache-name }}- ${{ runner.os }}-build- ${{ runner.os }}- - - name: Setup node - uses: actions/setup-node@v1 + - name: Setup Node.js + uses: actions/setup-node@v3 with: node-version: ${{ matrix.node }} + check-latest: true registry-url: https://registry.npmjs.org/ - - name: Compile typescript + - name: Compile TypeScript run: npm run build:ci - - name: Lint typescript + - name: Lint TypeScript run: npm run lint:ci diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 1f27ff4..3a87857 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,11 +8,12 @@ jobs: publish: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: actions/setup-node@v1 + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 with: - node-version: 14 + node-version: 18 + check-latest: true registry-url: https://registry.npmjs.org/ - - run: npm publish --unsafe-perm + - run: npm publish env: - NODE_AUTH_TOKEN: ${{secrets.NPM_SECRET}} + NODE_AUTH_TOKEN: ${{ secrets.NPM_SECRET }} diff --git a/.gitignore b/.gitignore index 7b39a2b..c236446 100644 --- a/.gitignore +++ b/.gitignore @@ -105,4 +105,4 @@ typings/ .tern-port package-lock.json yarn.lock -eslint_report.json +eslint_report.json \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..986f18a --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +16.9.0 \ No newline at end of file diff --git a/README.md b/README.md index a85c20b..8fdef71 100644 --- a/README.md +++ b/README.md @@ -27,32 +27,36 @@ You can also setup webhooks via Topgg.Webhook, look down below at the examples f If you're looking for an easy way to post your bot's stats (server count, shard count), check out [`topgg-autoposter`](https://npmjs.com/package/topgg-autoposter) ```js -const client = Discord.Client() // Your discord.js client or any other -const { AutoPoster } = require('topgg-autoposter') +const client = Discord.Client(); // Your discord.js client or any other +const { AutoPoster } = require("topgg-autoposter"); -AutoPoster('topgg-token', client) - .on('posted', () => { - console.log('Posted stats to Top.gg!') - }) +AutoPoster("topgg-token", client).on("posted", () => { + console.log("Posted stats to Top.gg!"); +}); ``` + With this your server count and shard count will be posted to Top.gg ## Webhook server ```js -const express = require('express') -const Topgg = require('@top-gg/sdk') +const express = require("express"); +const Topgg = require("@top-gg/sdk"); -const app = express() // Your express app +const app = express(); // Your express app -const webhook = new Topgg.Webhook('topggauth123') // add your Top.gg webhook authorization (not bot token) +const webhook = new Topgg.Webhook("topggauth123"); // add your Top.gg webhook authorization (not bot token) -app.post('/dblwebhook', webhook.listener(vote => { - // vote is your vote object - console.log(vote.user) // 221221226561929217 -})) // attach the middleware +app.post( + "/dblwebhook", + webhook.listener((vote) => { + // vote is your vote object + console.log(vote.user); // 221221226561929217 + }) +); // attach the middleware -app.listen(3000) // your port +app.listen(3000); // your port ``` + With this example, your webhook dashboard should look like this: ![](https://i.imgur.com/wFlp4Hg.png) diff --git a/package.json b/package.json index 165d85b..52da13c 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "@top-gg/sdk", - "version": "3.1.3", + "version": "3.1.4", "description": "Official Top.gg Node SDK", "main": "./dist/index.js", "scripts": { "build": "tsc", - "build:ci": "npm i --also=dev && tsc", + "build:ci": "npm i --include=dev && tsc", "docs": "typedoc", "prepublishOnly": "npm run build:ci", "lint": "eslint src/**/*.ts", @@ -23,25 +23,24 @@ }, "homepage": "https://topgg.js.org", "devDependencies": { - "@top-gg/eslint-config": "^0.0.2", - "@types/express": "^4.17.11", - "@types/node": "^14.14.41", - "@types/node-fetch": "^2.5.10", - "@typescript-eslint/eslint-plugin": "^4.26.0", - "@typescript-eslint/parser": "^4.26.0", - "eslint": "^7.27.0", - "eslint-config-prettier": "^8.3.0", - "eslint-plugin-jest": "^24.3.6", - "express": "^4.17.1", - "husky": "^6.0.0", - "lint-staged": "^11.0.0", - "prettier": "^2.3.0", - "typedoc": "^0.21.0", - "typescript": "^4.4.4" + "@top-gg/eslint-config": "^0.0.3", + "@types/express": "^4.17.17", + "@types/node": "^18.15.5", + "@typescript-eslint/eslint-plugin": "^5.56.0", + "@typescript-eslint/parser": "^5.56.0", + "eslint": "^8.36.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-jest": "^27.2.1", + "express": "^4.18.2", + "husky": "^8.0.3", + "lint-staged": "^13.2.0", + "prettier": "^2.8.6", + "typedoc": "^0.23.28", + "typescript": "^5.0.2" }, "dependencies": { - "node-fetch": "^2.6.1", - "raw-body": "^2.4.1" + "raw-body": "^2.5.2", + "undici": "^5.21.0" }, "types": "./dist/index.d.ts" } diff --git a/src/structs/Api.ts b/src/structs/Api.ts index bf89e2b..8f60782 100644 --- a/src/structs/Api.ts +++ b/src/structs/Api.ts @@ -1,8 +1,11 @@ -import fetch, { Headers } from "node-fetch"; +import { request, type Dispatcher } from "undici"; +import type { IncomingHttpHeaders } from "undici/types/header"; import ApiError from "../utils/ApiError"; import { EventEmitter } from "events"; +import { STATUS_CODES } from "http"; import { + APIOptions, Snowflake, BotStats, BotInfo, @@ -12,21 +15,16 @@ import { BotsQuery, } from "../typings"; -interface APIOptions { - /** - * Top.gg Token - */ - token?: string; -} - /** * Top.gg API Client for Posting stats or Fetching data + * * @example * ```js - * const Topgg = require(`@top-gg/sdk`) + * const Topgg = require("@top-gg/sdk"); * - * const api = new Topgg.Api('Your top.gg token') + * const api = new Topgg.Api("Your top.gg token"); * ``` + * * @link {@link https://topgg.js.org | Library docs} * @link {@link https://docs.top.gg | API Reference} */ @@ -34,8 +32,9 @@ export class Api extends EventEmitter { private options: APIOptions; /** * Create Top.gg API instance + * * @param {string} token Token or options - * @param {object?} options API Options + * @param {APIOptions} [options] API Options */ constructor(token: string, options: APIOptions = {}) { super(); @@ -46,33 +45,41 @@ export class Api extends EventEmitter { } private async _request( - method: string, + method: Dispatcher.HttpMethod, path: string, body?: Record ): Promise { - const headers = new Headers(); - if (this.options.token) headers.set("Authorization", this.options.token); - if (method !== "GET") headers.set("Content-Type", "application/json"); + const headers: IncomingHttpHeaders = {}; + if (this.options.token) headers["authorization"] = this.options.token; + if (method !== "GET") headers["content-type"] = "application/json"; let url = `https://top.gg/api${path}`; if (body && method === "GET") url += `?${new URLSearchParams(body)}`; - const response = await fetch(url, { + const response = await request(url, { method, headers, body: body && method !== "GET" ? JSON.stringify(body) : undefined, }); let responseBody; - if (response.headers.get("Content-Type")?.startsWith("application/json")) { - responseBody = await response.json(); + if ( + (response.headers["content-type"] as string)?.startsWith( + "application/json" + ) + ) { + responseBody = await response.body.json(); } else { - responseBody = await response.text(); + responseBody = await response.body.text(); } - if (!response.ok) { - throw new ApiError(response.status, response.statusText, response); + if (response.statusCode < 200 || response.statusCode > 299) { + throw new ApiError( + response.statusCode, + STATUS_CODES[response.statusCode] ?? "", + response + ); } return responseBody; @@ -80,21 +87,23 @@ export class Api extends EventEmitter { /** * Post bot stats to Top.gg - * @param {Object} stats Stats object - * @param {number} stats.serverCount Server count - * @param {number?} stats.shardCount Shard count - * @param {number?} stats.shardId Posting shard (useful for process sharding) - * @returns {BotStats} Passed object + * * @example * ```js * await api.postStats({ * serverCount: 28199, - * shardCount: 1 - * }) + * shardCount: 1, + * }); * ``` + * + * @param {object} stats Stats object + * @param {number} stats.serverCount Server count + * @param {number} [stats.shardCount] Shard count + * @param {number} [stats.shardId] Posting shard (useful for process sharding) + * @returns {BotStats} Passed object */ public async postStats(stats: BotStats): Promise { - if (!stats || !stats.serverCount) throw new Error("Missing Server Count"); + if (!stats?.serverCount) throw new Error("Missing Server Count"); /* eslint-disable camelcase */ await this._request("POST", "/bots/stats", { @@ -109,11 +118,10 @@ export class Api extends EventEmitter { /** * Get a bots stats - * @param {Snowflake} id Bot ID - * @returns {BotStats} Stats of bot requested + * * @example * ```js - * await api.getStats('461521980492087297') + * await api.getStats("461521980492087297"); * // => * { * serverCount: 28199, @@ -121,6 +129,9 @@ export class Api extends EventEmitter { * shards: [] * } * ``` + * + * @param {Snowflake} id Bot ID + * @returns {BotStats} Stats of bot requested */ public async getStats(id: Snowflake): Promise { if (!id) throw new Error("ID missing"); @@ -134,12 +145,14 @@ export class Api extends EventEmitter { /** * Get bot info - * @param {Snowflake} id Bot ID - * @returns {BotInfo} Info for bot + * * @example * ```js - * await api.getBot('461521980492087297') // returns bot info + * await api.getBot("461521980492087297"); // returns bot info * ``` + * + * @param {Snowflake} id Bot ID + * @returns {BotInfo} Info for bot */ public async getBot(id: Snowflake): Promise { if (!id) throw new Error("ID Missing"); @@ -148,14 +161,16 @@ export class Api extends EventEmitter { /** * Get user info - * @param {Snowflake} id User ID - * @returns {UserInfo} Info for user + * * @example * ```js - * await api.getUser('205680187394752512') + * await api.getUser("205680187394752512"); * // => - * user.username // Xignotic + * user.username; // Xignotic * ``` + * + * @param {Snowflake} id User ID + * @returns {UserInfo} Info for user */ public async getUser(id: Snowflake): Promise { if (!id) throw new Error("ID Missing"); @@ -164,18 +179,16 @@ export class Api extends EventEmitter { /** * Get a list of bots - * @param {BotsQuery} query Bot Query - * @returns {BotsResponse} Return response + * * @example * ```js * // Finding by properties * await api.getBots({ * search: { - * username: 'shiro', - * certifiedBot: true - * ...any other bot object properties - * } - * }) + * username: "shiro", + * certifiedBot: true, + * }, + * }); * // => * { * results: [ @@ -195,8 +208,8 @@ export class Api extends EventEmitter { * } * // Restricting fields * await api.getBots({ - * fields: ['id', 'username'] - * }) + * fields: ["id", "username"], + * }); * // => * { * results: [ @@ -213,10 +226,13 @@ export class Api extends EventEmitter { * ... * } * ``` + * + * @param {BotsQuery} query Bot Query + * @returns {BotsResponse} Return response */ public async getBots(query?: BotsQuery): Promise { if (query) { - if (query.fields instanceof Array) query.fields = query.fields.join(", "); + if (Array.isArray(query.fields)) query.fields = query.fields.join(", "); if (query.search instanceof Object) { query.search = Object.entries(query.search) .map(([key, value]) => `${key}: ${value}`) @@ -228,10 +244,10 @@ export class Api extends EventEmitter { /** * Get users who've voted - * @returns {ShortUser[]} Array of users who've voted + * * @example * ```js - * await api.getVotes() + * await api.getVotes(); * // => * [ * { @@ -249,6 +265,8 @@ export class Api extends EventEmitter { * ...more * ] * ``` + * + * @returns {ShortUser[]} Array of users who've voted */ public async getVotes(): Promise { if (!this.options.token) throw new Error("Missing token"); @@ -257,13 +275,15 @@ export class Api extends EventEmitter { /** * Get whether or not a user has voted in the last 12 hours - * @param {Snowflake} id User ID - * @returns {Boolean} Whether the user has voted in the last 12 hours + * * @example * ```js - * await api.hasVoted('205680187394752512') + * await api.hasVoted("205680187394752512"); * // => true/false * ``` + * + * @param {Snowflake} id User ID + * @returns {boolean} Whether the user has voted in the last 12 hours */ public async hasVoted(id: Snowflake): Promise { if (!id) throw new Error("Missing ID"); @@ -274,12 +294,14 @@ export class Api extends EventEmitter { /** * Whether or not the weekend multiplier is active - * @returns {Boolean} Whether the multiplier is active + * * @example * ```js - * await api.isWeekend() + * await api.isWeekend(); * // => true/false * ``` + * + * @returns {boolean} Whether the multiplier is active */ public async isWeekend(): Promise { return this._request("GET", "/weekend").then((x) => x.is_weekend); diff --git a/src/structs/Webhook.ts b/src/structs/Webhook.ts index 0bbd389..d257ce8 100644 --- a/src/structs/Webhook.ts +++ b/src/structs/Webhook.ts @@ -5,6 +5,7 @@ import { WebhookPayload } from "../typings"; export interface WebhookOptions { /** * Handles an error created by the function passed to Webhook.listener() + * * @default console.error */ error?: (error: Error) => void | Promise; @@ -12,25 +13,27 @@ export interface WebhookOptions { /** * Top.gg Webhook + * * @example * ```js - * const express = require('express') - * const { Webhook } = require(`@top-gg/sdk`) + * const express = require("express"); + * const { Webhook } = require("@top-gg/sdk"); * - * const app = express() - * const wh = new Webhook('webhookauth123') + * const app = express(); + * const wh = new Webhook("webhookauth123"); * - * app.post('/dblwebhook', wh.listener(vote => { + * app.post("/dblwebhook", wh.listener((vote) => { * // vote is your vote object e.g - * console.log(vote.user) // => 321714991050784770 - * })) + * console.log(vote.user); // => 321714991050784770 + * })); * - * app.listen(80) + * app.listen(80); * * // In this situation, your TopGG Webhook dashboard should look like * // URL = http://your.server.ip:80/dblwebhook * // Authorization: webhookauth123 * ``` + * * @link {@link https://docs.top.gg/resources/webhooks/#schema | Webhook Data Schema} * @link {@link https://docs.top.gg/resources/webhoooks | Webhook Documentation} */ @@ -39,6 +42,7 @@ export class Webhook { /** * Create a new webhook client instance + * * @param authorization Webhook authorization to verify requests */ constructor(private authorization?: string, options: WebhookOptions = {}) { @@ -86,21 +90,25 @@ export class Webhook { /** * Listening function for handling webhook requests + * * @example * ```js - * app.post('/webhook', wh.listener((vote) => { - * console.log(vote.user) // => 395526710101278721 - * })) + * app.post("/webhook", wh.listener((vote) => { + * console.log(vote.user); // => 395526710101278721 + * })); * ``` - * @param fn Vote handling function, this function can also throw an error to allow for the webhook to resend from Top.gg + * * @example * ```js * // Throwing an error to resend the webhook - * app.post('/webhook/', wh.listener((vote) => { + * app.post("/webhook/", wh.listener((vote) => { * // for example, if your bot is offline, you should probably not handle votes and try again - * if (bot.offline) throw new Error('Bot offline') - * })) + * if (bot.offline) throw new Error('Bot offline'); + * })); * ``` + * + * @param fn Vote handling function, this function can also throw an error to + * allow for the webhook to resend from Top.gg * @returns An express request handler */ public listener( @@ -135,13 +143,14 @@ export class Webhook { /** * Middleware function to pass to express, sets req.vote to the payload + * * @deprecated Use the new {@link Webhook.listener | .listener()} function * @example * ```js - * app.post('/dblwebhook', wh.middleware(), (req, res) => { + * app.post("/dblwebhook", wh.middleware(), (req, res) => { * // req.vote is your payload e.g - * console.log(req.vote.user) // => 395526710101278721 - * }) + * console.log(req.vote.user); // => 395526710101278721 + * }); * ``` */ public middleware() { @@ -153,8 +162,6 @@ export class Webhook { const response = await this._parseRequest(req, res); if (!response) return; res.sendStatus(204); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore deprecated unsafe assignment req.vote = response; next(); }; diff --git a/src/typings.ts b/src/typings.ts index eb26f3a..b1340f6 100644 --- a/src/typings.ts +++ b/src/typings.ts @@ -1,296 +1,179 @@ -/** - * Discord ID - */ +export interface APIOptions { + /** Top.gg token */ + token?: string; +} + +/** Discord ID */ export type Snowflake = string; export interface BotInfo { - /** - * The id of the bot - */ + /** The id of the bot */ id: Snowflake; - /** - * The username of the bot - */ + /** The username of the bot */ username: string; - /** - * The discriminator of the bot - */ + /** The discriminator of the bot */ discriminator: string; - /** - * The avatar hash of the bot's avatar - */ + /** The avatar hash of the bot's avatar */ avatar?: string; - /** - * The cdn hash of the bot's avatar if the bot has none - */ + /** The cdn hash of the bot's avatar if the bot has none */ defAvatar: string; - /** - * The URL for the banner image - */ + /** The URL for the banner image */ bannerUrl?: string; /** * The library of the bot + * * @deprecated */ lib: string; - /** - * The prefix of the bot - */ + /** The prefix of the bot */ prefix: string; - /** - * The short description of the bot - */ + /** The short description of the bot */ shortdesc: string; - /** - * The long description of the bot. Can contain HTML and/or Markdown - */ + /** The long description of the bot. Can contain HTML and/or Markdown */ longdesc: string; - /** - * The tags of the bot - */ + /** The tags of the bot */ tags: string[]; - /** - * The website url of the bot - */ + /** The website url of the bot */ website?: string; - /** - * The support server invite code of the bot - */ + /** The support server invite code of the bot */ support?: string; - /** - * The link to the github repo of the bot - */ + /** The link to the github repo of the bot */ github?: string; - /** - * The owners of the bot. First one in the array is the main owner - */ + /** The owners of the bot. First one in the array is the main owner */ owners: Snowflake[]; - /** - * The guilds featured on the bot page - */ + /** The guilds featured on the bot page */ guilds: Snowflake[]; - /** - * The custom bot invite url of the bot - */ + /** The custom bot invite url of the bot */ invite?: string; - /** - * The date when the bot was approved (in ISO 8601) - */ + /** The date when the bot was approved (in ISO 8601) */ date: string; - /** - * The certified status of the bot - */ + /** The certified status of the bot */ certifiedBot: boolean; - /** - * The vanity url of the bot - */ + /** The vanity url of the bot */ vanity?: string; - /** - * The amount of upvotes the bot has - */ + /** The amount of upvotes the bot has */ points: number; - /** - * The amount of upvotes the bot has this month - */ + /** The amount of upvotes the bot has this month */ monthlyPoints: number; - /** - * The guild id for the donatebot setup - */ + /** The guild id for the donatebot setup */ donatebotguildid: Snowflake; } export interface BotStats { - /** - * The amount of servers the bot is in - */ + /** The amount of servers the bot is in */ serverCount?: number; /** - * The amount of servers the bot is in per shard. Always present but can be empty. (Only when receiving stats) + * The amount of servers the bot is in per shard. Always present but can be + * empty. (Only when receiving stats) */ shards?: number[]; - /** - * The shard ID to post as (only when posting) - */ + /** The shard ID to post as (only when posting) */ shardId?: number; - /** - * The amount of shards a bot has - */ + /** The amount of shards a bot has */ shardCount?: number; } export interface UserInfo { - /** - * The id of the user - */ + /** The id of the user */ id: Snowflake; - /** - * The username of the user - */ + /** The username of the user */ username: string; - /** - * The discriminator of the user - */ + /** The discriminator of the user */ discriminator: string; - /** - * The avatar hash of the user's avatar - */ + /** The avatar hash of the user's avatar */ avatar?: string; - /** - * The cdn hash of the user's avatar if the user has none - */ + /** The cdn hash of the user's avatar if the user has none */ defAvatar: string; - /** - * The bio of the user - */ + /** The bio of the user */ bio?: string; - /** - * The banner image url of the user - */ + /** The banner image url of the user */ banner?: string; - /** - * The social usernames of the user - */ + /** The social usernames of the user */ social: { - /** - * The youtube channel id of the user - */ + /** The youtube channel id of the user */ youtube?: string; - /** - * The reddit username of the user - */ + /** The reddit username of the user */ reddit?: string; - /** - * The twitter username of the user - */ + /** The twitter username of the user */ twitter?: string; - /** - * The instagram username of the user - */ + /** The instagram username of the user */ instagram?: string; - /** - * The github username of the user - */ + /** The github username of the user */ github?: string; }; - /** - * The custom hex color of the user - */ + /** The custom hex color of the user */ color: string; - /** - * The supporter status of the user - */ + /** The supporter status of the user */ supporter: boolean; - /** - * The certified status of the user - */ + /** The certified status of the user */ certifiedDev: boolean; - /** - * The mod status of the user - */ + /** The mod status of the user */ mod: boolean; - /** - * The website moderator status of the user - */ + /** The website moderator status of the user */ webMod: boolean; - /** - * The admin status of the user - */ + /** The admin status of the user */ admin: boolean; } export interface BotsQuery { - /** - * The amount of bots to return. Max. 500 - */ + /** The amount of bots to return. Max. 500 */ limit?: number; - /** - * Amount of bots to skip - */ + /** Amount of bots to skip */ offset?: number; - /** - * A search string in the format of "field: value field2: value2" - */ + /** A search string in the format of "field: value field2: value2" */ search?: | { [key in keyof BotInfo]: string; } | string; - /** - * The field to sort by. Prefix with "-"" to reverse the order - */ + /** The field to sort by. Prefix with "-"" to reverse the order */ sort?: string; - /** - * A list of fields to show. - */ + /** A list of fields to show. */ fields?: string[] | string; } export interface BotsResponse { - /** - * The matching bots - */ + /** The matching bots */ results: BotInfo[]; - /** - * The limit used - */ + /** The limit used */ limit: number; - /** - * The offset used - */ + /** The offset used */ offset: number; - /** - * The length of the results array - */ + /** The length of the results array */ count: number; - /** - * The total number of bots matching your search - */ + /** The total number of bots matching your search */ total: number; } export interface ShortUser { - /** - * User's ID - */ + /** User's ID */ id: Snowflake; - /** - * User's username - */ + /** User's username */ username: string; - /** - * User's discriminator - */ + /** User's discriminator */ discriminator: string; - /** - * User's avatar hash - */ + /** User's avatar hash */ avatar: string; } export interface WebhookPayload { - /** - * If webhook is a bot: ID of the bot that received a vote - */ + /** If webhook is a bot: ID of the bot that received a vote */ bot?: Snowflake; - /** - * If webhook is a server: ID of the server that received a vote - */ + /** If webhook is a server: ID of the server that received a vote */ guild?: Snowflake; - /** - * ID of the user who voted - */ + /** ID of the user who voted */ user: Snowflake; /** - * The type of the vote (should always be "upvote" except when using the test button it's "test") + * The type of the vote (should always be "upvote" except when using the test + * button it's "test") */ type: string; /** - * Whether the weekend multiplier is in effect, meaning users votes count as two + * Whether the weekend multiplier is in effect, meaning users votes count as + * two */ isWeekend?: boolean; - /** - * Query parameters in vote page in a key to value object - */ + /** Query parameters in vote page in a key to value object */ query: | { [key: string]: string; diff --git a/src/utils/ApiError.ts b/src/utils/ApiError.ts index 1441953..b4df924 100644 --- a/src/utils/ApiError.ts +++ b/src/utils/ApiError.ts @@ -1,18 +1,15 @@ -import { Response } from "node-fetch"; +import type { Dispatcher } from "undici"; + const tips = { 401: "You need a token for this endpoint", 403: "You don't have access to this endpoint", }; -/** - * API Error - */ +/** API Error */ export default class TopGGAPIError extends Error { - /** - * Possible response from Request - */ - public response?: Response; - constructor(code: number, text: string, response: Response) { + /** Possible response from Request */ + public response?: Dispatcher.ResponseData; + constructor(code: number, text: string, response: Dispatcher.ResponseData) { if (code in tips) { super(`${code} ${text} (${tips[code as keyof typeof tips]})`); } else { diff --git a/typedoc.json b/typedoc.json index 78bd1df..4e3b397 100644 --- a/typedoc.json +++ b/typedoc.json @@ -1,10 +1,9 @@ { - "out": "./docs/", - "entryPoints": ["src/index.ts"], - "readme": "./README.md", - "name": "@top-gg/sdk", - "excludeExternals": true, - "excludePrivate": true, - "excludeInternal": true, - "theme": "minimal" - } \ No newline at end of file + "out": "./docs/", + "entryPoints": ["src/index.ts"], + "readme": "./README.md", + "name": "@top-gg/sdk", + "excludeExternals": true, + "excludePrivate": true, + "excludeInternal": true +}