An unofficial TypeScript wrapper for v4 of IGDB.com API.
npm i igdb-ts
- Obtain
Client ID
andClient Secret
from Twitch.tv. - To obtain the above, follow instructions provided by IGDB here.
- Assign authorized URLs. For development, add
http://localhost
.
- You should treat your
Client Secret
like a password. - This package is intended for backend use only.
- IGDB OAuth token limits. See here.
- IGDB's notes on CORS.
import { IGDB } from 'igdb-ts';
CLIENT_ID
- Client ID retrieved from TwitchCLIENT_SECRET
- Client Secret retrieved from TwitchCLIENT_TOKEN
- Twitch App Access Token (optional). You should pass this if you have a stored app access token.onAccessTokenRetrieved
- Callback for you to store your access token.
- Passes
clientToken
andtokenExpiry
(in milliseconds from Epoch). - Will not call on
init()
if givenCLIENT_TOKEN
- Will be called whenever your access token expires and will generate a new one for you automatically.
RATE_OPTIONS
- Axio Rate Limit Options. Default settings are 4 requests / second as per IGDB documentation.
const CLIENT_ID = "MY_CLIENT_ID";
const CLIENT_SECRET = "MY_CLIENT_SECRET";
const CLIENT_TOKEN = "MY_CLIENT_TOKEN";
const RATE_OPTIONS = { maxRPS: 4 }
//Callback to save token to storage
const onAccessTokenRetrieved = (token: string, tokenExpiry: number) => {
//Save to storage
}
const igdb = new IGDB();
igdb.init(CLIENT_ID, CLIENT_SECRET, CLIENT_TOKEN, onAccessTokenRetrieved, RATE_OPTIONS?);
All endpoints described in the API documentation are available. For example:
const games = await igdb.getGames();
const characters = await igdb.getCharacters()
To build your own custom endpoint calls with your own typed response use the get<T>()
function.
interface GameCount {
count: number
}
//Get Game Count
const gameCount = await igdb.get<GameCount>("games/count");
By default all fields (*) are returned unless stated otherwise.
Fields are typed based on the keys of each endpoint response.
import { SearchableIGDBOptions } from 'igdb-ts';
const options: SearchableIGDBOptions<Game> = {
fields: ["name", "rating", "summary"]
}
const games = await igdb.getGames(options);
Fields do not have typing. It is recommended you use provided enums instead.
import { GameFields, GenreReferenceFields, UntypedIGDBOptions } from 'igdb-ts';
interface GameGenre {
id: number,
name: string
rating: number,
genres: { id: number, name: string }[]
}
const options: UntypedIGDBOptions = {
fields: [GameFields.NAME, GameFields.RATING, GenreReferenceFields.NAME]
}
const games = await igdb.get<GameGenre[]>("games", options);
Exclude fields are typed.
import { SearchableIGDBOptions } from 'igdb-ts'
const options: SearchableIGDBOptions<Game> = {
exclude: ["rating"]
}
const games = await igdb.getGames(options);
Exclude fields are not typed.
import { GameFields, UntypedIGDBOptions, Endpoints } from 'igdb-ts'
const options: UntypedIGDBOptions = {
exclude: [GameFields.NAME]
}
const games = await igdb.get(Endpoints.GAME, options);
To use expanders, you must use the generic get()
function as expanders will not follow the shape of defined endpoint response types.
To help build your expander calls use provided enums.
import { GameFields, GenreReferenceFields, UntypedIGDBOptions, Endpoints } from 'igdb-ts'
interface GameRatingGenre{
id: number,
name: string,
rating: number,
genres: { id: number, name; string }[]
}
const options: UntypedIGDBOptions = {
fields: [GameFields.NAME, GameFields.RATING, GenreReferenceFields.NAME]
}
const games = await igdb.get<GameRatingGenre>(Endpoints.GAME, options);
Filters are not typed. This is because you can filter on expander fields e.g. platform.releaseDates
.
Click here to view all available filter methods.
Use enums provided to ensure you are using correct fields.
import { GameFields, SearchableIGDBOptions } from 'igdb-ts';
const options: SearchableIGDBOptions<Game> = {
filter: {
filters: [
{ GameFields.RATING, ">=", 80 },
{ GameFields.PLATFORMS, "=", "[130, 48]" }
],
operators: ["&"]
}
}
const games = await igdb.getGames(options);
Combined filters are supported.
Note: You cannot have a combinedFilter
and filter
at the same time.
import { Filter, SearchableIGDBOptions, GameFields } from 'igdb-ts'
// Games released for both PC (6), and PS4 (48) and also has the genre simulator (13).
const filter1: Filter = {
filters: [
{ field: GameFields.PLATFORMS, postfix: "=", value: "[6, 48]" },
{ field: GameFields.GENRES, postfix: "=", value: 13 }
],
operators: ["&"]
}
// Games released for both Switch (130), and PS4 (48) and also has the genre Role-Playing (13).
const filter2: Filter = {
filters: [
{ field: GameFields.PLATFORMS, postfix: "=", value: "[130, 48]" },
{ field: GameFields.GENRES, postfix: "=", value: 12 }
],
operators: ["&"]
}
const options: SearchableIGDBOptions<Game> = {
combinedFilter: {
filters: [filter1, filter2],
operators: ["|"]
}
}
const games = await igdb.getGames(options);
Sorting fields are not typed as you can sort on expander fields. Use provided enums where possible.
import { GameFields, SearchableIGDBOptions } from 'igdb-ts';
const options: SearchableIGDBOptions<Game> = {
sortBy: {
field: GameFields.NAME,
order: "asc"
}
}
const games = await igdb.getGames(options);
Searchable endpoints:
- Characters
- Collections
- Games
- People
- Platforms
- Themes
Prebuilt endpoint calls have been typed so you can only use search for the endpoints above.
//Will work
const games = await igdb.getGames({ search: "witcher" });
//Will show compiler error
const companies = await igdb.getCompanies({ search: "cd projekt" })
Custom calls are not typed. Both will compile however, you will encounter an error response from IGDB for trying to search the Companies endpoint.
import { Endpoints } from 'igdb-ts';
//Will work
const games = await igdb.get(Endpoints.GAME, { search: "witcher" });
//Will work but will throw error when called
const companies = await igdb.get(Endpoints.COMPANY, { search: "cd projekt" })
Provide an offset and limit.
import { SearchableIGDBOptions } from 'igdb-ts'
const options: SearchableIGDBOptions<Game> = {
limit: 20,
offset: 10,
}
const games = await igdb.getGames(options);
Multiquery is supported. Return type is any[]
. Therefore you will have to cast each query reponse yourself.
import { GameFields, PlatformReferenceFields, Query } from 'igdb-ts'
interface PlayStationGameResult {
name: string,
result: {
id: number,
name: string,
platforms: { id: number, name: string }[]
}
}
interface PlatformCountResult {
name: string,
count: number
}
//Get PlayStation 4 Exclusives
const query1: Query = {
endpoint: "game",
resultName: "PlayStation Games",
options: {
fields: [GameFields.NAME, PlatformReferenceFields.NAME],
filter: {
filters: [
{ GameFields.PLATFORM, "!=", null },
{ GameFields.PLATFORM, "==", 48 }],
],
operators: ["&"]
}
limit: 1,
}
};
//Get Count of Platforms
const query2: Query = {
endpoint: "platforms/count",
resultName: "Platform Count"
}
const multiQuery = await igdb.multiQuery([query1, query2]);
const playstationGames = multiQuery[0] as PlayStationGameResult
const platformCount = mulitQuery[1] as PlatformCountResult
Image options can be found here.
import { ImageOptions } from 'igdb-ts'
const options: ImageOptions = {
imageId: "mnljdjtrh44x4snmierh",
size: "t_thumb",
retina: true,
}
const imageUrl = igdb.getImageUrl(options);