igdb-client
Version:
147 lines • 5.88 kB
JavaScript
import axios from "axios";
import { logger } from "./utils/logger";
import { EmptyGame } from "./utils/empty";
export class IGDBClient {
/**
* Get the request header that contains the Client ID and access token.
*
* This method throws an error if the client is not connected.
*
* @returns The request headers object.
* @throws {Error} If the client is not connected.
*/
getRequestHeader() {
if (!this.accessToken) {
logger.error("Access token is not set.");
throw new Error("The Client is not connected. Access token isn't generated.");
}
return {
headers: {
"Client-Id": this.clientID,
"Authorization": `Bearer ${this.accessToken}`
}
};
}
/**
* Construct a new IGDBClient instance. If no client ID or secret is provided, it will use the TWITCH_CLIENT_ID and TWITCH_CLIENT_SECRET environment variables.
*
* @param twitchClientID Your Twitch Developer Dashboard client ID.
* @param twitchClientSecret Your Twitch Developer Dashboard client secret.
*/
constructor(twitchClientID = "", twitchClientSecret = "") {
this.igdbBaseURL = "https://api.igdb.com/v4";
this.axiosClient = axios.create({ baseURL: this.igdbBaseURL });
this.accessToken = "";
this.expiresIn = 0;
this.isConnected = false;
this.tokenTimeout = null;
this.clientID = twitchClientID !== null && twitchClientID !== void 0 ? twitchClientID : process.env.TWITCH_CLIENT_ID;
this.clientSecret = twitchClientSecret !== null && twitchClientSecret !== void 0 ? twitchClientSecret : process.env.TWITCH_CLIENT_SECRET;
this.grantType = "client_credentials";
this.authURL = `https://id.twitch.tv/oauth2/token?client_id=${this.clientID}&client_secret=${this.clientSecret}&grant_type=${this.grantType}`;
}
/**
* Connects to the IGDB API by getting an access token using the Twitch client credentials.
* Updates the request header with the new access token for authentication.
*
* @returns {Promise<this>} Returns the IGDBClient instance on successful connection,
* or an error if the connection fails.
*/
async connect() {
if (this.isConnected) {
logger.info("Already connected to IGDB");
return this;
}
if (!this.clientID || !this.clientSecret) {
logger.error("Twitch client ID and secret are required to connect to the IGDB API.");
logger.info("Either pass the client ID and secret as arguments to the constructor or set the TWITCH_CLIENT_ID and TWITCH_CLIENT_SECRET environment variables.");
throw new Error("Failed to connect to IGDB.");
}
try {
await this.getAccessToken();
logger.info("Connected to IGDB");
return this;
}
catch (error) {
logger.error(error);
throw new Error("Failed to connect to IGDB.");
}
}
/**
* Disconnects from the IGDB API by clearing the access token timeout and setting the connection status to false.
*
* @returns {void} Does not return any value.
*/
disconnect() {
if (this.tokenTimeout) {
clearTimeout(this.tokenTimeout);
}
this.isConnected = false;
}
/**
* Requests an access token using the Twitch client credentials.
* Updates the request header with the new access token for authentication.
* Refreshes the access token when it is about to expire.
*
* @returns {Promise<void>} Resolves when the access token is set.
* @throws {Error} If the request for an access token fails.
* @private
*/
async getAccessToken() {
try {
const response = await this.axiosClient.post(this.authURL);
this.accessToken = response.data.access_token;
this.expiresIn = response.data.expires_in;
this.tokenTimeout = setTimeout(() => {
logger.info("Access token is about to expire");
try {
this.getAccessToken();
logger.info("Access token refreshed");
}
catch (error) {
logger.error("Failed to refresh the access token.");
throw new Error("Failed to refresh the access token.");
}
}, this.expiresIn - 600);
}
catch (error) {
logger.error(error);
throw new Error("Failed to get the access token.");
}
}
/**
* Fetches a list of games from the IGDB API that match the given name.
*
* @param name - The name of the game to search for.
* @returns A promise that resolves to the list of games matching the search query.
* @throws Logs an error if the request fails.
*/
async getGames(name) {
try {
const response = await this.axiosClient.post("/games", `fields *; search \"${name}\";`, this.getRequestHeader());
return response.data;
}
catch (error) {
logger.error(error);
return [];
}
}
/**
* Fetches a game by its ID from the IGDB API.
*
* @param id - The ID of the game to fetch.
* @returns A promise that resolves to the fetched game.
* @throws Logs an error if the request fails.
*/
async getGame(id) {
try {
const response = await this.axiosClient.post(`/games/`, `fields *; where id = ${id};`, this.getRequestHeader());
return response.data;
}
catch (error) {
logger.error(error);
return [EmptyGame];
}
}
}
//# sourceMappingURL=IGDBClient.js.map