From 9750ebc24a5d91a3d07ddfad184fed99d41fac68 Mon Sep 17 00:00:00 2001 From: Ollie Jennings Date: Sat, 18 May 2024 15:01:03 +0100 Subject: [PATCH] feat(utils): added a regionToCluster util method --- README.md | 71 +++++++++++++++++++----------------- __tests__/unit/utils.test.ts | 35 ++++++++++++++++++ src/index.ts | 11 +++--- src/utils.ts | 31 ++++++++++++++++ 4 files changed, 110 insertions(+), 38 deletions(-) create mode 100644 __tests__/unit/utils.test.ts create mode 100644 src/utils.ts diff --git a/README.md b/README.md index e53ac81..0a84e6e 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,14 @@ > Node.JS minimal Riot API client written in Typescript - ### Features -* Rate limiting through [@fightmegg/riot-rate-limiter](https://github.com/fightmegg/riot-rate-limiter) -* Automatic retries -* TypeScript typings -* 100% endpoint coverage (incl. DDragon) -* Caching with custom ttls per endpoint -* Request prioritization - +- Rate limiting through [@fightmegg/riot-rate-limiter](https://github.com/fightmegg/riot-rate-limiter) +- Automatic retries +- TypeScript typings +- 100% endpoint coverage (incl. DDragon) +- Caching with custom ttls per endpoint +- Request prioritization ## Installation @@ -26,35 +24,35 @@ $ npm install @fightmegg/riot-api ## Usage ```ts -import { RiotAPI, RiotAPITypes, PlatformId } from '@fightmegg/riot-api' +import { RiotAPI, RiotAPITypes, PlatformId } from "@fightmegg/riot-api"; (async () => { - const rAPI = new RiotAPI('RGAPI-KEY'); + const rAPI = new RiotAPI("RGAPI-KEY"); - const summoner = await rAPI.summoner.getBySummonerName({ - region: PlatformId.EUW1, - summonerName: "Demos Kratos", - }); -})() + const summoner = await rAPI.summoner.getBySummonerName({ + region: PlatformId.EUW1, + summonerName: "Demos Kratos", + }); +})(); ``` ## Config ```ts const config: RiotAPITypes.Config = { - debug: false, - cache: { - cacheType: 'ioredis', // local or ioredis - client: 'redis://localhost:6379', // leave null if client is local - ttls: { - byMethod: { - [RiotAPITypes.METHOD_KEY.SUMMONER.GET_BY_SUMMONER_NAME]: 5000, // ms - } - } - } -} - -const rAPI = new RiotAPI('RGAPI-TOKEN', config); + debug: false, + cache: { + cacheType: "ioredis", // local or ioredis + client: "redis://localhost:6379", // leave null if client is local + ttls: { + byMethod: { + [RiotAPITypes.METHOD_KEY.SUMMONER.GET_BY_SUMMONER_NAME]: 5000, // ms + }, + }, + }, +}; + +const rAPI = new RiotAPI("RGAPI-TOKEN", config); ``` ## Error handling @@ -69,14 +67,13 @@ Caching is turned off by default, but with the cache property in the config you When setting up the cache, you can change the `ttl` of each method / endpoint individually. This is done through the `METHOD_KEY` type which can be found in the [typings file](https://github.com/fightmegg/riot-api/blob/master/src/%40types/index.ts#L92). - ## DDragon We also fully support [DataDragon](https://developer.riotgames.com/docs/lol#data-dragon) which can be accessed in two ways: ```ts // ... -const rAPI = new RiotAPI('RGAPI-KEY'); +const rAPI = new RiotAPI("RGAPI-KEY"); const latestV = await rAPI.ddragon.versions.latest(); const champs = await rAPI.ddragon.champion.all(); @@ -85,7 +82,7 @@ const champs = await rAPI.ddragon.champion.all(); If you want to just use static data only, then you can do the following: ```ts -import { DDragon } from '@fightmegg/riot-api'; +import { DDragon } from "@fightmegg/riot-api"; const ddragon = new DDragon(); const champs = await ddragon.champion.all(); @@ -93,6 +90,16 @@ const champs = await ddragon.champion.all(); Just like the main API, we have full TypeScript typings for DDragon endpoints. Please note we **do not** support caching for DDragon endpoints. +## regionToCluster + +A helper method to make it easier to determing which cluster you want to hit based on the users region + +```ts +import { regionToCluster } from "@fightmegg/riot-api"; + +const cluster = regionToCluster("EUW1"); // outputs "EUROPE" +``` + ## TypeScript typing ```ts @@ -111,14 +118,12 @@ If you want to see want the rate-limiter is currently doing, we use the [debug]( DEBUG=riotapi* node ... ``` - ## Testing Unit tests: `npm test` E2E tests: `npm run test:e2e` - ## Planned features - [ ] Custom Caches diff --git a/__tests__/unit/utils.test.ts b/__tests__/unit/utils.test.ts new file mode 100644 index 0000000..05037dc --- /dev/null +++ b/__tests__/unit/utils.test.ts @@ -0,0 +1,35 @@ +import { PlatformId } from "@fightmegg/riot-rate-limiter"; +import { regionToCluster } from "../../src/utils"; + +describe("utils", () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe("regionToCluster", () => { + test("should return correct cluster for each region", () => { + expect(regionToCluster(PlatformId.NA1)).toEqual(PlatformId.AMERICAS); + expect(regionToCluster(PlatformId.BR1)).toEqual(PlatformId.AMERICAS); + expect(regionToCluster(PlatformId.LA1)).toEqual(PlatformId.AMERICAS); + expect(regionToCluster(PlatformId.LA2)).toEqual(PlatformId.AMERICAS); + + expect(regionToCluster(PlatformId.KR)).toEqual(PlatformId.ASIA); + expect(regionToCluster(PlatformId.JP1)).toEqual(PlatformId.ASIA); + + expect(regionToCluster(PlatformId.EUW1)).toEqual(PlatformId.EUROPE); + expect(regionToCluster(PlatformId.EUNE1)).toEqual(PlatformId.EUROPE); + expect(regionToCluster(PlatformId.TR1)).toEqual(PlatformId.EUROPE); + expect(regionToCluster(PlatformId.RU)).toEqual(PlatformId.EUROPE); + + expect(regionToCluster(PlatformId.OC1)).toEqual(PlatformId.SEA); + expect(regionToCluster(PlatformId.PH2)).toEqual(PlatformId.SEA); + expect(regionToCluster(PlatformId.SG2)).toEqual(PlatformId.SEA); + expect(regionToCluster(PlatformId.TH2)).toEqual(PlatformId.SEA); + expect(regionToCluster(PlatformId.TW2)).toEqual(PlatformId.SEA); + expect(regionToCluster(PlatformId.VN2)).toEqual(PlatformId.SEA); + + // @ts-expect-error -- testing invalid input + expect(regionToCluster("invalid")).toEqual(PlatformId.AMERICAS); + }); + }); +}); diff --git a/src/index.ts b/src/index.ts index 37c6de4..dc90ccd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,17 +1,18 @@ import { - RiotRateLimiter, - METHODS, HOST, + METHODS, PlatformId, + RiotRateLimiter, } from "@fightmegg/riot-rate-limiter"; import Bottleneck from "bottleneck"; +import debug from "debug"; import { RedisOptions } from "ioredis"; import { compile } from "path-to-regexp"; import qs from "querystring"; -import { RiotAPITypes, Leaves } from "./@types"; +import { Leaves, RiotAPITypes } from "./@types"; import { MemoryCache, RedisCache } from "./cache"; import { DDragon } from "./ddragon"; -import debug from "debug"; +import { regionToCluster } from "./utils"; const debugCache = debug("riotapi:cache"); @@ -33,7 +34,7 @@ const getPath = (key: Leaves): string => { return path; }; -export { RiotAPITypes, PlatformId, DDragon }; +export { DDragon, PlatformId, RiotAPITypes, regionToCluster }; export class RiotAPI { readonly cache?: MemoryCache | RedisCache; diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..c5778ad --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,31 @@ +import { PlatformId } from "@fightmegg/riot-rate-limiter"; +import { RiotAPITypes } from "./@types"; + +export function regionToCluster( + region: RiotAPITypes.LoLRegion +): RiotAPITypes.Cluster { + switch (region) { + case PlatformId.NA1: + case PlatformId.BR1: + case PlatformId.LA1: + case PlatformId.LA2: + return PlatformId.AMERICAS; + case PlatformId.KR: + case PlatformId.JP1: + return PlatformId.ASIA; + case PlatformId.EUW1: + case PlatformId.EUNE1: + case PlatformId.TR1: + case PlatformId.RU: + return PlatformId.EUROPE; + case PlatformId.OC1: + case PlatformId.PH2: + case PlatformId.SG2: + case PlatformId.TH2: + case PlatformId.TW2: + case PlatformId.VN2: + return PlatformId.SEA; + default: + return PlatformId.AMERICAS; + } +}