Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
578 changes: 374 additions & 204 deletions README.md

Large diffs are not rendered by default.

53 changes: 51 additions & 2 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,52 @@
# Examples
# Twisted Examples

Here you are example of each api endpoint of league of legends
A runnable example for (almost) every Riot API endpoint that [`twisted`](../) wraps —
League of Legends, Teamfight Tactics, Riot Account, Data Dragon and Clash.

Each file exports a single named `async` function that performs a small, self-contained
call and logs a friendly summary of the result. They double as living documentation:
read them to see the exact shape of a request and its response.

## How to run

Examples need a Riot API key, read from `process.env.RIOT_API_KEY`. Grab one from the
[Riot Developer Portal](https://developer.riotgames.com/).

```bash
# Run every example
RIOT_API_KEY=RGAPI-xxxx yarn example

# Run a single example by name (case-insensitive substring match)
RIOT_API_KEY=RGAPI-xxxx yarn example account
RIOT_API_KEY=RGAPI-xxxx yarn example datadragon
```

When you pass a name, the runner matches every exported function whose name *contains*
it, runs them, and prints the JSON they return. With no argument, it runs them all in
sequence (with a short delay between calls to stay friendly to rate limits).

> **Use your own account.** The examples target a few demo Riot IDs defined in
> [`config/config.ts`](./config/config.ts). Edit that file to point at your own
> account (`summonerName` / `tagLine` / `region` / `regionGroup`) before running.

## What's inside

| Folder | Category | Examples | Highlights |
| --- | --- | --- | --- |
| [`riot/`](./riot) | **Riot Account** (Account-V1) | 2 | Resolve a Riot ID ↔ PUUID; the entry point for everything else. Routed by region *group*. |
| [`lol/`](./lol) | **League of Legends** | 19 | Summoner, League/ranked, Champion mastery & rotation, Match-V5, Spectator-V5, Challenges, Status. |
| [`lol/*.DataDragon.ts`](./lol) | **Data Dragon** (static CDN) | 12 | Champions, runes, maps, queues, versions and more — no API key, no rate limits. |
| [`lol/deprecated/`](./lol/deprecated) | **LoL (deprecated)** | 11 | Older endpoints kept for reference (summoner-by-name, Match-V4, Spectator-V4, …). Prefer the current ones. |
| [`tft/`](./tft) | **Teamfight Tactics** | 9 | Summoner, league by tier/summoner, Match-V1, Spectator, static files. |
| [`clash/`](./clash) | **Clash** | 2 | List tournaments and fetch one by id. |

## Regions vs region groups

Riot uses two routing concepts, both demonstrated in the examples and documented in
[`config/config.ts`](./config/config.ts):

- **`Regions`** — platform routing (`EUW1`, `KR`, `NA1`, …) used by most LoL/TFT endpoints.
- **`RegionGroups`** — routing groups (`AMERICAS`, `ASIA`, `EUROPE`, `SEA`) used by
Match-V5, TFT-Match and the Account API.

The library's types enforce which one each endpoint accepts.
38 changes: 27 additions & 11 deletions example/clash/ClashTournamentById.example.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
import { LolApi } from '../../src'
import { config } from '../config/config'

const api = new LolApi()

/**
* CLASH-V1 — Fetch a single Clash tournament by its id.
*
* There is no fixed tournament id to demo, so we first list the active
* tournaments and reuse the first one's id. Clash is often idle, so we guard
* against an empty list. This endpoint uses the platform `Regions` value.
*/
export async function clashTournamentById () {
const { region } = config
const {
response: [
{
id
}
]
} = await api.Clash.getTournaments(region)
return api.Clash.getTournamentById(id, region)
const lolApi = new LolApi()

// 1. List the active Clash tournaments to discover a valid id
const { response: tournaments } = await lolApi.Clash.getTournaments(config.region)

// 2. Bail out gracefully when no tournament is currently scheduled
if (tournaments.length === 0) {
console.log(`No active Clash tournaments on ${config.region} right now.`)
return null
}

// 3. Reuse the first tournament's id to fetch its full detail
const [{ id }] = tournaments
const { response: tournament } = await lolApi.Clash.getTournamentById(id, config.region)

console.log(`Tournament #${tournament.id} — ${tournament.nameKey}`)
console.log(`Theme : ${tournament.themeId}`)
console.log(`Schedule: ${tournament.schedule.length} phase(s)`)

return tournament
}
26 changes: 19 additions & 7 deletions example/clash/ClashTournamentList.example.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
import { LolApi } from '../../src'
import { config } from '../config/config'

const api = new LolApi()

/**
* CLASH-V1 — List the active Clash tournaments for a platform region.
*
* Clash is a scheduled competitive mode, so the list is often empty when no
* tournament is running. This endpoint uses the platform `Regions` value.
*/
export async function clashTournamentList () {
const { region } = config
const {
response
} = await api.Clash.getTournaments(region)
return response
const lolApi = new LolApi()

// 1. Fetch every active/scheduled Clash tournament on the platform region
const { response: tournaments } = await lolApi.Clash.getTournaments(config.region)

console.log(`Active Clash tournaments on ${config.region}: ${tournaments.length}`)

// 2. Print a short summary for each tournament (id + theme)
for (const tournament of tournaments) {
console.log(`#${tournament.id} — themeId ${tournament.themeId} (${tournament.nameKey})`)
}

return tournaments
}
45 changes: 40 additions & 5 deletions example/config/config.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,62 @@
import { Constants } from '../../src'
import { Regions, RegionGroups, AccountAPIRegionGroups } from '../../src/constants'
import { Levels } from '../../src/constants/levels'

export const config = {
/**
* Shared configuration used across the examples.
*
* Riot IDs are made of a `gameName` + `tagLine` (the value after the `#`),
* e.g. `Thebausffs#COOL`.
*
* Three different "region" concepts show up in the Riot API:
* - `Regions` (platform routing, e.g. `EUW1`, `KR`, `NA1`) — most LoL/TFT endpoints.
* - `RegionGroups` (`AMERICAS` | `ASIA` | `EUROPE` | `SEA`) — Match-V5 / TFT-Match.
* - `AccountAPIRegionGroups` (`RegionGroups` without `SEA`) — the Account-V1 API.
*/
interface ExampleAccount {
/** Riot ID game name (the part before the `#`). */
summonerName: string
/** Riot ID tag line (the part after the `#`). */
tagLine: string
/** Platform region for LoL/TFT platform endpoints. */
region: Regions
/** Routing value for the Account-V1 API (americas / asia / europe). */
regionGroup: AccountAPIRegionGroups
}

export const config: ExampleAccount = {
summonerName: 'Thebausffs',
tagLine: 'COOL',
region: Constants.Regions.EU_WEST,
regionGroup: Constants.RegionGroups.AMERICAS,
regionGroup: Constants.RegionGroups.EUROPE
}

interface ExampleTftAccount extends ExampleAccount {
/** Routing value for the TFT Match-V1 API. */
tftRegion: RegionGroups
}

export const configTft = {
export const configTft: ExampleTftAccount = {
summonerName: 'Meinya',
tagLine: 'NA1',
region: Constants.Regions.AMERICA_NORTH,
regionGroup: Constants.RegionGroups.AMERICAS,
tftRegion: Constants.RegionGroups.AMERICAS
}

interface ExampleChallengesAccount extends ExampleAccount {
/** A challenge id (see the Challenges-V1 config endpoint). */
challengeId: number
/** Tier used when querying challenge leaderboards. */
level: Levels
}

// Used for challengeID
export const configChallenges = {
export const configChallenges: ExampleChallengesAccount = {
summonerName: 'Night Owl',
tagLine: 'ryi',
region: Constants.Regions.AMERICA_NORTH,
regionGroup: Constants.RegionGroups.AMERICAS,
challengeId: 101106, // ARAM Eradication
level: Levels.CHALLENGER
}
}
30 changes: 25 additions & 5 deletions example/lol/ChallengerLeagueByQueue.example.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,29 @@
import { LolApi } from '../../src'
import { LolApi, Constants } from '../../src'
import { config } from '../config/config'
import { Queues } from '../../src/constants'

const api = new LolApi()

/**
* LEAGUE-V4 — Get the Challenger league for a given ranked queue.
*
* Returns the single apex league for the region/queue, with every Challenger
* player listed under `entries`.
*/
export async function challengerLeagueByQueueExample () {
return await api.League.getChallengerLeaguesByQueue(Queues.RANKED_SOLO_5x5, config.region)
const lolApi = new LolApi()

// Fetch the Challenger ladder for solo/duo queue on this region
const { response: league } = await lolApi.League.getChallengerLeaguesByQueue(
Constants.Queues.RANKED_SOLO_5x5,
config.region
)

console.log(`Challenger league "${league.name}" (${league.queue})`)
console.log(`Players: ${league.entries.length}`)

// Highlight the highest-LP player in the ladder
const top = [...league.entries].sort((a, b) => b.leaguePoints - a.leaguePoints)[0]
if (top) {
console.log(`Top player: ${top.leaguePoints} LP — ${top.wins}W/${top.losses}L`)
}

return league
}
75 changes: 56 additions & 19 deletions example/lol/Challenges.example.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,65 @@
import { RiotApi } from '../../src'
import { LolApi } from '../../src/apis/lol/lol'
import { LolApi, RiotApi } from '../../src'
import { configChallenges } from '../config/config'

export async function challengesV1Example() {
const rApi = new RiotApi()
const api = new LolApi()
/**
* LOL-CHALLENGES-V1 — Explore the Challenges system.
*
* Challenges are achievement-style goals with levels (IRON … CHALLENGER) and
* leaderboards. This example walks the main read endpoints:
* - PlayerChallenges : a single player's progress (needs a PUUID)
* - Leaderboards : the top players for one challenge at a level
* - Configs : the static config for every challenge
* - ChallengeConfig : the static config for one challenge
* - Percentiles : value distribution across ALL challenges
* - ChallengePercentiles: value distribution for one challenge
*/
export async function challengesV1Example () {
const riotApi = new RiotApi()
const lolApi = new LolApi()

const { response: { puuid } } = await rApi.Account.getByRiotId(configChallenges.summonerName, configChallenges.tagLine, configChallenges.regionGroup)
// 1. Resolve the Riot ID into a PUUID (PlayerChallenges is keyed by PUUID)
const { response: account } = await riotApi.Account.getByRiotId(
configChallenges.summonerName,
configChallenges.tagLine,
configChallenges.regionGroup
)

const playerChallenges = (await api.Challenges.PlayerChallenges(puuid, configChallenges.region)).response
// console.log('Found total challenge points:', playerChallenges.totalPoints)
// 2. The player's own challenge progress and summed points
const { response: playerChallenges } = await lolApi.Challenges.PlayerChallenges(
account.puuid,
configChallenges.region
)
console.log(`${account.gameName}#${account.tagLine} total points: ${playerChallenges.totalPoints.current}/${playerChallenges.totalPoints.max} (${playerChallenges.totalPoints.level})`)

const leaderboards = (await api.Challenges.Leaderboards(configChallenges.challengeId, configChallenges.level, configChallenges.region, { limit: 5 })).response
// console.log(`Top 5 ${configChallenges.level} for ARAM Eradication for `, leaderboards)
// 3. Top 5 players for our example challenge at the configured level
const { response: leaderboards } = await lolApi.Challenges.Leaderboards(
configChallenges.challengeId,
configChallenges.level,
configChallenges.region,
{ limit: 5 }
)
console.log(`Leaderboard entries for challenge ${configChallenges.challengeId}: ${leaderboards.length}`)

const configs = (await api.Challenges.Configs(configChallenges.region)).response
// console.log("Config thresholds for the first of all basic challenges:", configs[0])
// 4. Static config for every challenge on this region
const { response: configs } = await lolApi.Challenges.Configs(configChallenges.region)
console.log(`Total challenges configured: ${configs.length}`)

const config = (await api.Challenges.ChallengeConfig(configChallenges.challengeId, configChallenges.region)).response
// console.log('Challenge Configuration for ARAM Eradication', config)
// 5. Static config for just our example challenge
const { response: challengeConfig } = await lolApi.Challenges.ChallengeConfig(
configChallenges.challengeId,
configChallenges.region
)
console.log(`Challenge ${challengeConfig.id} has leaderboard: ${challengeConfig.leaderboard}`)

const distributions = (await api.Challenges.Percentiles(configChallenges.region)).response
// console.log("Distribution for ARAM Eradication:", distributions[configChallenges.challengeId])
// 6. Value distribution across ALL challenges, then narrowed to our challenge
const { response: percentiles } = await lolApi.Challenges.Percentiles(configChallenges.region)
console.log(`Percentile data available for ${Object.keys(percentiles).length} challenges`)

const distribution = (await api.Challenges.ChallengePercentiles(configChallenges.challengeId, configChallenges.region)).response
// console.log("Distribution for ARAM Eradication:", distribution)
}
const { response: challengePercentiles } = await lolApi.Challenges.ChallengePercentiles(
configChallenges.challengeId,
configChallenges.region
)
console.log(`Levels with a percentile for challenge ${configChallenges.challengeId}: ${Object.keys(challengePercentiles).join(', ')}`)

return playerChallenges
}
37 changes: 30 additions & 7 deletions example/lol/ChampionMasteryByPUUID.example.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,34 @@
import { RiotApi } from '../../src'
import { LolApi } from '../../src'
import { LolApi, RiotApi } from '../../src'
import { config } from '../config/config'

const rApi = new RiotApi()
const api = new LolApi()

/**
* CHAMPION-MASTERY-V4 — Get all champion mastery entries for a player by PUUID.
*
* Mastery is keyed by PUUID, so we first resolve the account's PUUID through
* the Riot Account API, then fetch every champion the player has points on.
*/
export async function championMasteryByPUUID () {
const { response: { puuid } } = await rApi.Account.getByRiotId(config.summonerName, config.tagLine, config.regionGroup)
return await api.Champion.masteryByPUUID(puuid, config.region)
const riotApi = new RiotApi()
const lolApi = new LolApi()

// 1. Resolve the Riot ID (gameName#tagLine) into a PUUID
const { response: account } = await riotApi.Account.getByRiotId(
config.summonerName,
config.tagLine,
config.regionGroup
)

// 2. Fetch every champion mastery entry on the player's platform region
const { response: masteries } = await lolApi.Champion.masteryByPUUID(account.puuid, config.region)

console.log(`Player : ${account.gameName}#${account.tagLine}`)
console.log(`Champions : ${masteries.length}`)

// 3. The API already returns the list sorted by championPoints (highest first)
const top = masteries[0]
if (top) {
console.log(`Top champion : id ${top.championId} (level ${top.championLevel}, ${top.championPoints} pts)`)
}

return masteries
}
Loading
Loading