UNPKG

@phalcode/ts-igdb-client

Version:

A Typescript client and request builder for IGDB using ts-apicalypse

155 lines (132 loc) 5.97 kB
# ts-igdb-client A Typescript client and request builder for [IGDB](https://api-docs.igdb.com/#about) using [ts-apicalypse](https://github.com/magne4000/ts-apicalypse/tree/main/ts-apicalypse). ## Usage All IGDB types are generated from [IGDB proto file](https://api.igdb.com/v4/igdbapi.proto) and used to type this lib. ### Auth Usually you'll want your IGDB queries to be authenticated. See the following example ```ts import { twitchAccessToken, igdb } from 'ts-igdb-client'; const twitchSecrets = { client_id: '...', client_secret: '...', } // generate a twitch access token const accessToken = await twitchAccessToken(twitchSecrets); // generate an IGDB client with twitch credentials const client = igdb(twitchSecrets.client_id, accessToken); // build and execute a query const { data } = await client.request(...).execute(); ``` ### Simple request ```ts import { fields, exclude, where } from 'ts-igdb-client'; // type of `data` is automagically infered const { data } = await client.request('/games') // Start building a request that will be executed on `/games` endpoint. // Type validation and autocompletion support for all endpoints. .pipe( fields(['name']), // `fields` are type checked. Here valid fields would be 'id' | 'name' | 'games' | 'collection' | ... | // 'games.id' | 'games.name' | ... | 'games.*' | // 'collection.id' | 'collection.name' | ... | 'collection.*' // or even deeply nested one like 'collection.games.name' or 'collection.games.*', etc. where('created_at', '<', now), // The prop, the operator and the value are type checked ).execute(); // Execute the query // another example using `exclude` operator const { data } = await request('/games') .pipe( fields('*'), // All fields... exclude(['name']) // ... except name ).execute(); ``` ### Request nested fields ```ts import { fields, sort, limit, offset } from 'ts-igdb-client'; // type of `data` is automagically infered const { data } = await client.request('/games') .pipe( fields(['name', 'games', 'collection.*']), sort('created_at', '<'), // sort, asc by default limit(10), // pagination offset(10), // pagination ).execute() ``` ### Request with complex conditions ```ts import { fields, or, and, where, whereIn, WhereFlags, WhereInFlags } from 'ts-igdb-client'; // type of `data` is automagically infered const { data } = await client.request('/external_games') .pipe( fields('*'), // demo of possible combinations and( where('id', '>', 4), where('id', '>=', 4), where('id', '<', 4), where('id', '<=', 4), where('name', '=', 'zelda'), // name is zelda (case sensitive) where('name', '~', 'zelda'), // name is zelda (case insensitive) where('name', '!=', 'zelda'), // name is not zelda where('name', '=', 'zelda', WhereFlags.STARTSWITH), // name starts with zelda (also works with ~) where('name', '=', 'zelda', WhereFlags.ENDSWITH), // name ends with zelda (also works with ~) where('name', '=', 'zelda', WhereFlags.CONTAINS), // name contains zelda (also works with ~) where('name', '=', null), // no name where('name', '!=', null), // name exists, where('collection.games.name', '=', 'zelda'), // nested types are also supported or( where('name', '=', 'zelda'), whereIn('name', ['mario', 'luigi']), whereIn('games', [1, 2], WhereInFlags.AND), // Results whose games ids includes 1 and 2 whereIn('games', [1, 2], WhereInFlags.OR), // Results whose games ids includes 1 or 2 whereIn('games', [1, 2], WhereInFlags.NAND), // Results whose games ids does not contain both 1 and 2, but can be 1 or 2 whereIn('games', [1, 2], WhereInFlags.NOR), // Results whose games ids does not contain 1 or does not contain 2 whereIn('games', [1, 2], WhereInFlags.EXACT), // Results whose exclusive games ids are 1 and 2, whereIn('collection.games.name', ['mario', 'luigi']), // nested types are also supported ) ) ).execute(); ``` ### Count query Most query will return requested fields as response data. But _count_ actually return data differently: ```ts import { fields, exclude } from 'ts-igdb-client'; // type of `data` is automagically infered const { data } = await client.request('games/count') // Here the query is tagged as a "count" query because it ends with `/count` .pipe() // you can have no operators, or specify some conditions .execute(); ``` ### Multi-query request One can query multiple endpoints at once with a `multi` query ```ts import { request, client, fields, isNamed } from 'ts-igdb-client'; // type of `data` is automagically infered const { data } = await client.multi( // `alias` must be used inside `multi` to alias the queries // you can use `request` directly imported from `ts-igdb-client` or `client.request` request('/games').alias("alias1").pipe(fields(['...'])), request('/games/count').alias("alias2").pipe(fields(['...'])), request('/external_games').alias("alias3").pipe(fields(['...'])), ).execute(); // you can then use `isNamed` type-guard to help you narrow data types const result = data[0]; if (isNamed(result, 'alias1')) { result.result... } else if (isNamed(result, 'alias2')) { result.count... } ``` ### Webhooks ```ts // Register a new webhook const { data } = await client.webhooks.register('games', { url: 'https://...', method: 'create', secret: 'MySeCrEt', }); // Retrieve existing webhooks ... const { data } = await client.webhooks.get(); // ... or one webhook in particular const { data } = await client.webhooks.get('someWebhookID'); // Delete existing webhook const { data } = await client.webhooks.delete('someWebhookID'); // Test webhook const { data } = await client.webhooks.test('games', 1234, 1337); ```