riotapi-fetch-typed 1.1.3-dev → 1.2.0-dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,109 +1,110 @@
1
- <a href="https://github.com/TournamentStats/riotapi-fetch-typed/actions/workflows/test.yml"><img src="https://github.com/TournamentStats/riotapi-fetch-typed/actions/workflows/test.yml/badge.svg" alt="test workflow"></a>
2
- <a href="https://www.npmjs.com/package/riotapi-fetch-typed"><img src="https://img.shields.io/npm/v/riotapi-fetch-typed.svg" alt="npm registry"></a>
3
-
4
- # riotapi-fetch-typed
5
-
6
- Fetch the Riot Games API with type safety, thanks to the OpenAPI specification.
7
-
8
- ## Features
9
-
10
- - Just a thin wrapper around fetch
11
- - (Almost) Fully Type-safe
12
- - Regions (based on API Route)
13
- - API Routes
14
- - HTTP Methods
15
- - Request Body
16
- - Response Body
17
- - Errors
18
- - Almost instant updates with zero maintenance, Updates on the API just need a regeneration of the src/types/openapi.d.ts file using `openapi-typescript`
19
- - supports all endpoints that are in the [OpenAPI specification](https://github.com/MingweiSamuel/riotapi-schema)
20
-
21
- ## Usage
22
-
23
- ### Without Error throwing
24
-
25
- ```typescript
26
- import { createRiotFetch } from "riotapi-fetch-typed";
27
-
28
- const riotFetch = createRiotFetch({ apiKey: process.env.RIOT_API_KEY! });
29
-
30
- const puuid =
31
- "Zz2sEt4n_mfS37AyXSqXnNw4eXDHHRfsYXD2FQb7jOLIrttOjtIe88cu_fKqwkPVgCSc_4slSNSrbg";
32
- // theoretically the route could support autofill, but current vscode typescript language doesn't support it, sadge. See below for issues
33
- const { response, data, error } = await riotFetch(
34
- `/riot/account/v1/accounts/by-puuid/${puuid}`,
35
- {
36
- region: "europe", // type-safe
37
- }
38
- );
39
-
40
- if (!error) {
41
- const { gameName, tagLine } = data;
42
- }
43
- ```
44
-
45
- ### With Error throwing
46
-
47
- ```typescript
48
- const riotFetch = createRiotFetch({
49
- apiKey: process.env.RIOT_API_KEY!,
50
- throwOnResponseError: true,
51
- });
52
-
53
- try {
54
- const { response, data } = await riotFetch("/lol/tournament/v5/codes", {
55
- region: "europe",
56
- method: "post", // also type-safe
57
- body: {
58
- enoughPlayers: false,
59
- mapType: "SUMMONERS_RIFT",
60
- pickType: "TOURNAMENT_DRAFT",
61
- spectatorType: "ALL",
62
- teamSize: 5,
63
- }, // body is also fully typed and annotated (if exists)
64
- });
65
- const tournamentCodes = data;
66
- } catch (e: unknown) {
67
- if (e instanceof RiotError) {
68
- console.error(e.statusCode, e.data);
69
- }
70
- }
71
- ```
72
-
73
- ## Installation
74
-
75
- Install it using your package manager:
76
-
77
- ```bash
78
- $ npm install riot-games-fetch-typed
79
- # or
80
- $ pnpm install riot-games-fetch-typed
81
- # or
82
- $ yarn install riot-games-fetch-typed
83
- # or
84
- $ bun install riot-games-fetch-typed
85
- ```
86
-
87
- ## Autocomplete related issues
88
-
89
- This library would be much more DX-friendly if typescript could autocomplete / give suggestions for template literal types. I think in theory
90
- this could be possible, but in reality I have no clue if the typescript eco-system would allow something like that.
91
-
92
- Issues/PRs i found that maybe relates to the autocompletion of template literals.
93
-
94
- - https://github.com/microsoft/TypeScript/issues/57902
95
- - https://github.com/microsoft/TypeScript/pull/59794
96
- - https://github.com/microsoft/TypeScript/issues/61217
97
-
98
- ## How it works
99
-
100
- This module uses the `openapi-typescript` module to generate typescript data from the Riot API OpenAPI Specification, that itself is generated from the officially documentation. Huge thanks to [Mingwei Samuel](https://github.com/MingweiSamuel) who provides them at https://github.com/MingweiSamuel/riotapi-schema. With these type information, typescript's flexible typing system including template literals and type infering, we can infer the type of response and method and applicable regions from the fetch parameters.
101
-
102
- ## Contributing
103
-
104
- Feel free to contribute.
105
-
106
- ## This also exist
107
-
108
- - https://openapi-ts.dev/openapi-fetch/
109
- - Much more feature complete, riotapi-fetch-typed is tailored for the Riot API and would require much more work to be as general as openapi-fetch
1
+ <a href="https://github.com/TournamentStats/riotapi-fetch-typed/actions/workflows/test.yml"><img src="https://github.com/TournamentStats/riotapi-fetch-typed/actions/workflows/test.yml/badge.svg" alt="test workflow"></a>
2
+ <a href="https://www.npmjs.com/package/riotapi-fetch-typed"><img src="https://img.shields.io/npm/v/riotapi-fetch-typed.svg" alt="npm registry"></a>
3
+
4
+ # riotapi-fetch-typed
5
+
6
+ Fetch the Riot Games API with type safety, thanks to the OpenAPI specification.
7
+
8
+ ## Features
9
+
10
+ - Just a thin wrapper around fetch
11
+ - (Almost) Fully Type-safe
12
+ - Regions (based on API Route)
13
+ - API Routes
14
+ - HTTP Methods
15
+ - Request Body
16
+ - Query Parameters
17
+ - Response Body
18
+ - Errors
19
+ - Almost instant updates with zero maintenance, Updates on the API just need a regeneration of the src/types/openapi.d.ts file using `openapi-typescript`
20
+ - supports all endpoints that are in the [OpenAPI specification](https://github.com/MingweiSamuel/riotapi-schema)
21
+
22
+ ## Usage
23
+
24
+ ### Without Error throwing
25
+
26
+ ```typescript
27
+ import { createRiotFetch } from "riotapi-fetch-typed";
28
+
29
+ const riotFetch = createRiotFetch({ apiKey: process.env.RIOT_API_KEY! });
30
+
31
+ const puuid =
32
+ "Zz2sEt4n_mfS37AyXSqXnNw4eXDHHRfsYXD2FQb7jOLIrttOjtIe88cu_fKqwkPVgCSc_4slSNSrbg";
33
+ // theoretically the route could support autofill, but current vscode typescript language doesn't support it, sadge. See below for issues
34
+ const { response, data, error } = await riotFetch(
35
+ `/riot/account/v1/accounts/by-puuid/${puuid}`,
36
+ {
37
+ region: "europe", // type-safe
38
+ }
39
+ );
40
+
41
+ if (!error) {
42
+ const { gameName, tagLine } = data;
43
+ }
44
+ ```
45
+
46
+ ### With Error throwing
47
+
48
+ ```typescript
49
+ const riotFetch = createRiotFetch({
50
+ apiKey: process.env.RIOT_API_KEY!,
51
+ throwOnResponseError: true,
52
+ });
53
+
54
+ try {
55
+ const { response, data } = await riotFetch("/lol/tournament/v5/codes", {
56
+ region: "europe",
57
+ method: "post", // also type-safe
58
+ body: {
59
+ enoughPlayers: false,
60
+ mapType: "SUMMONERS_RIFT",
61
+ pickType: "TOURNAMENT_DRAFT",
62
+ spectatorType: "ALL",
63
+ teamSize: 5,
64
+ }, // body is also fully typed and annotated (if exists)
65
+ });
66
+ const tournamentCodes = data;
67
+ } catch (e: unknown) {
68
+ if (e instanceof RiotError) {
69
+ console.error(e.statusCode, e.data);
70
+ }
71
+ }
72
+ ```
73
+
74
+ ## Installation
75
+
76
+ Install it using your package manager:
77
+
78
+ ```bash
79
+ $ npm install riot-games-fetch-typed
80
+ # or
81
+ $ pnpm install riot-games-fetch-typed
82
+ # or
83
+ $ yarn install riot-games-fetch-typed
84
+ # or
85
+ $ bun install riot-games-fetch-typed
86
+ ```
87
+
88
+ ## Autocomplete related issues
89
+
90
+ This library would be much more DX-friendly if typescript could autocomplete / give suggestions for template literal types. I think in theory
91
+ this could be possible, but in reality I have no clue if the typescript eco-system would allow something like that.
92
+
93
+ Issues/PRs i found that maybe relates to the autocompletion of template literals.
94
+
95
+ - https://github.com/microsoft/TypeScript/issues/57902
96
+ - https://github.com/microsoft/TypeScript/pull/59794
97
+ - https://github.com/microsoft/TypeScript/issues/61217
98
+
99
+ ## How it works
100
+
101
+ This module uses the `openapi-typescript` module to generate typescript data from the Riot API OpenAPI Specification, that itself is generated from the officially documentation. Huge thanks to [Mingwei Samuel](https://github.com/MingweiSamuel) who provides them at https://github.com/MingweiSamuel/riotapi-schema. With these type information, typescript's flexible typing system including template literals and type infering, we can infer the type of response and method and applicable regions from the fetch parameters.
102
+
103
+ ## Contributing
104
+
105
+ Feel free to contribute.
106
+
107
+ ## This also exist
108
+
109
+ - https://openapi-ts.dev/openapi-fetch/
110
+ - Much more feature complete, riotapi-fetch-typed is tailored for the Riot API and would require much more work to be as general as openapi-fetch
package/dist/index.cjs CHANGED
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ Queues: () => Queues,
23
24
  RiotError: () => RiotError,
24
25
  createRiotFetch: () => createRiotFetch
25
26
  });
@@ -93,8 +94,45 @@ function createRiotFetch({
93
94
  };
94
95
  };
95
96
  }
97
+ var Queues = {
98
+ CUSTOM: 0,
99
+ HEXAKILL: 75,
100
+ URF: [76, 1900],
101
+ AR_URF: 900,
102
+ ARAM: {
103
+ BUTCHERS_BRIDGE: 100,
104
+ HOWLING_ABYSS: 450,
105
+ ALL: [100, 450]
106
+ },
107
+ ALL_RANDOM: 325,
108
+ BLIND: 430,
109
+ DRAFT: 400,
110
+ QUICKPLAY: 490,
111
+ RANKED_SOLO: 420,
112
+ RANKED_FLEX: 440,
113
+ CLASH: {
114
+ SUMMONERS_RIFT: 700,
115
+ HOWLING_ABYSS: 720,
116
+ ARAM: 720,
117
+ ALL: [700, 720]
118
+ },
119
+ COOP_VS_AI: {
120
+ INTRO: 870,
121
+ BEGINNER: 880,
122
+ INTERMEDIATE: 890,
123
+ ALL: [870, 880, 890]
124
+ },
125
+ DOOM_BOTS: 960,
126
+ ONE_FOR_ALL: 1020,
127
+ NEXUS_BLITZ: 1300,
128
+ SPELLBOOK: 1400,
129
+ ARENA: [1700, 1710],
130
+ SWARM: [1810, 1820, 1830, 1840],
131
+ TUTORIAL: [2e3, 2010, 2020]
132
+ };
96
133
  // Annotate the CommonJS export names for ESM import in node:
97
134
  0 && (module.exports = {
135
+ Queues,
98
136
  RiotError,
99
137
  createRiotFetch
100
138
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { paths, components } from './types/openapi.d.js';\n\nexport * from './types/openapi.d.js';\n\n\n/** Every possible API path, based on the OpenAPI document */\nexport type Paths = keyof paths;\n\n/**\n * Type util that replaces all occurences of curly brackets pairs in a string literal type to string placeholders,\n * resulting in a template literal type. For that it recursively tests the string for curly bracket pairs.\n *\n * @example TemplatifyPath<'summoner/{summonerName}/ranked'> -> `summoner/${string}/ranked`\n */\nexport type TemplatifyPath<Path extends string> =\n\tPath extends `${infer Start}/{${string}}${infer End}`\n\t\t? `${Start}/${string}${TemplatifyPath<End>}`\n\t\t: Path;\n\n\n/** Every possible API path, but templatified */\nexport type TemplatePaths = TemplatifyPath<Paths>;\n\n/** Splits a Path by `/` into an array */\nexport type SplitPath<Path extends string> = Path extends `${infer Head}/${infer Tail}`\n\t? [Head, ...SplitPath<Tail>]\n\t: [Path];\n\n/**\n * Compares two splitted paths.\n *\n * Type is true if both splitted paths have the same length and every segment of Concrete extends its corresponding segment Template\n * */\nexport type MatchSegments<Template extends string[], Concrete extends string[]> =\n Template extends [infer TemplateSegment, ...infer TemplateRest]\n \t? Concrete extends [infer ConcreteSegment, ...infer ConcreteRest]\n \t\t? ConcreteSegment extends TemplateSegment\n \t\t\t? TemplateRest extends string[]\n \t\t\t\t? ConcreteRest extends string[]\n \t\t\t\t\t? MatchSegments<TemplateRest, ConcreteRest>\n \t\t\t\t\t: never\n \t\t\t\t: never\n \t\t\t: false\n \t\t: Concrete extends []\n \t\t\t? Template extends []\n \t\t\t\t? true\n \t\t\t\t: false\n \t\t\t: false\n \t: Template extends []\n \t\t? Concrete extends []\n \t\t\t? true\n \t\t\t: false\n \t\t: false;\n\n/**\n * Gives all API Paths that matches the path. Basically the reverse operation of TemplatifyPath\n *\n * @example ResolveTemplatePath<`/riot/account/v1/accounts/by-puuid/${string}`>\n * -> \"/riot/account/v1/accounts/by-puuid/{puuid}\"\n *\n * @example ResolveTemplatePath<`/riot/account/v1/accounts/by-riot-id/gameName/gameTag`>\n * -> \"/riot/account/v1/accounts/by-riot-id/{gameName}/{tagLine}\"\n */\nexport type ResolveTemplatePath<Path extends TemplatePaths> = {\n\t[P in Paths]: MatchSegments<SplitPath<TemplatifyPath<P>>, SplitPath<Path>> extends true ? P : never\n}[Paths];\n\nexport type HTTPMethods = 'get' | 'put' | 'post' | 'delete' | 'options' | 'head' | 'patch' | 'trace';\n\n/**\n * Get all available methods for a specific API path\n */\nexport type Methods<Path extends Paths> = Exclude<keyof {\n\t[K in keyof paths[Path] as paths[Path][K] extends undefined ? never : K]: paths[Path][K]\n}, 'parameters'>;\n\n/** Get all possible responses for a specific API path and method */\nexport type GetResponses<Path extends Paths, Method extends Methods<Path>> =\n\tpaths[Path][Method] extends { responses: infer Responses }\n\t\t? Responses\n\t\t: never;\n\n\n/** Get the response body for a specific API path, method and status code */\nexport type GetResponseBody<Path extends Paths, Method extends Methods<Path>, StatusCode extends number> =\n\tGetResponses<Path, Method> extends Record<StatusCode, { content?: { 'application/json': infer Body } }>\n\t\t? Body\n\t\t: never;\n\n\nexport type GetRequestBody<Path extends Paths, Method extends Methods<Path>> =\n paths[Path][Method] extends { requestBody?: never }\n \t? { body?: never }\n \t: paths[Path][Method] extends { requestBody: { content: { 'application/json': infer U } } }\n \t\t? { body: U }\n \t\t: paths[Path][Method] extends { requestBody?: { content: { 'application/json': infer U } } }\n \t\t\t? { body?: U }\n \t\t\t: unknown;\n\n\n/** Get the query parameters for a specific API path and method */\nexport type GetQuery<Path extends Paths, Method extends Methods<Path>> =\n Pick<paths[Path][Method]['parameters'], 'query'>;\n\n\n/** Regions for /riot/account/ endpoints */\nexport type AccountRegion = 'americas' | 'asia' | 'europe';\n/** Regions for some lol and tft endpoints */\nexport type LolRegion = 'br1' | 'eun1' | 'euw1' | 'jp1' | 'kr' | 'la1' | 'la2' | 'me1' | 'na1' | 'oc1' | 'ph2' | 'ru' | 'sg2' | 'th2' | 'tr1' | 'tw2' | 'vn2';\n/** Regions for lol and tft matches endpoints */\nexport type MatchRegion = 'americas' | 'asia' | 'europe' | 'sea';\n/** Regions for /lor/ endpoints */\nexport type LorRegion = 'americas' | 'europe' | 'sea';\n/** Regions for /val/ endpoints */\nexport type ValorantRegion = 'ap' | 'br' | 'eu' | 'latam' | 'na' | 'esports' | 'kr';\n\n\n/** Get the relevant subdomains, depending on the endpoint */\n// i dont like eslint indenting here\n/* eslint-disable @stylistic/indent */\nexport type GetSubdomain<Path extends TemplatePaths> =\n\tPath extends `/riot/account/${string}` ? AccountRegion :\n\tPath extends `/lol/champion-mastery/${string}` ? LolRegion :\n\tPath extends `/lol/platform/${string}` ? LolRegion :\n\tPath extends `/lol/clash/${string}` ? LolRegion :\n\tPath extends `/lol/league-exp/${string}` ? LolRegion :\n\tPath extends `/lol/league/${string}` ? LolRegion :\n\tPath extends `/lol/challenges/${string}` ? LolRegion :\n\tPath extends `/lol/rso-match/${string}` ? MatchRegion :\n\tPath extends `/lol/status/${string}` ? LolRegion :\n\tPath extends `/lor/deck/${string}` ? LorRegion :\n\tPath extends `/lor/inventory/${string}` ? LorRegion :\n\tPath extends `/lor/match/${string}` ? LorRegion | 'apac' :\n\tPath extends `/lor/ranked/${string}` ? LorRegion :\n\tPath extends `/lor/status/${string}` ? LorRegion :\n\tPath extends `/lol/match/${string}` ? MatchRegion :\n\tPath extends `/lol/spectator/${string}` ? LolRegion :\n\tPath extends `/fulfillment/${string}` ? LolRegion :\n\tPath extends `/lol/summoner/${string}` ? LolRegion :\n\tPath extends `/tft/league/${string}` ? LolRegion :\n\tPath extends `/tft/match/${string}` ? MatchRegion | 'esports' | 'esportseu' :\n\tPath extends `/tft/status/${string}` ? LolRegion :\n\tPath extends `/tft/summoner/${string}` ? LolRegion :\n\t// seems like only americas but not sure\n\tPath extends `/lol/tournament-stub/${string}` ? 'americas' :\n\t// don't know, can't see in api reference\n\tPath extends `/lol/tournament/${string}` ? LolRegion | MatchRegion :\n\t// The api docs do not include all regions for console, but for stability we will just include them\n\tPath extends `/val/match/console/${string}` ? ValorantRegion :\n\tPath extends `/val/console/ranked/${string}` ? ValorantRegion :\n\tPath extends `/val/content/${string}` ? ValorantRegion :\n\tPath extends `/val/match/${string}` ? ValorantRegion :\n\tPath extends `/val/ranked/${string}` ? ValorantRegion :\n\tPath extends `/val/status/${string}` ? Exclude<ValorantRegion, 'esports'>\n\t: never;\n/* eslint-enable @stylistic/indent */\n\n/** Typical structure for a RiotError json object. */\nexport type RiotErrorData = components['schemas']['Error'];\n\n/**\n * Error Class for a 4xx/5xx response code in a fetch to the Riot API\n */\nexport class RiotError extends Error {\n\tconstructor(message: string, statusCode: number, data?: RiotErrorData) {\n\t\tsuper(message);\n\t\tthis.statusCode = statusCode;\n\t\tthis.data = data;\n\t}\n\tstatusCode: number;\n\tdata: RiotErrorData | undefined;\n}\n\n/**\n * Type guard to check if an object is in the form of an riot error.\n * The API may return a structure like that on error, but we cannot be sure.\n *\n * @param obj obj to be checked\n * @returns true if obj has the form of RiotErroData\n */\nfunction isRiotErrorData(obj: unknown): obj is RiotErrorData {\n\tif (typeof obj !== 'object' || obj === null) return false;\n\n\tconst data = obj as RiotErrorData;\n\n\tif (data.status !== undefined) {\n\t\tif (typeof data.status !== 'object') {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ('status_code' in data.status && typeof data.status.status_code !== 'number')\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tif ('message' in data.status && typeof data.status.message !== 'string')\t\t{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n\n/**\n * This is a mess. I am sorry for this type abonimation.\n *\n * @template Path the Path of the API route\n * @template ChosenMethod the Method that is chosen, has to be one of the available methods of the Path\n * @template ThrowOnError Wether createRiotFetch is configured to throw on http errors or not\n * @template error response.ok, used for type narrowing\n */\nexport type RiotFetchReturn<\n\tPath extends TemplatePaths,\n\tChosenMethod extends Methods<ResolveTemplatePath<Path>>,\n\tThrowOnError extends boolean,\n\terror extends boolean,\n> = ThrowOnError extends true\n\t? error extends false\n\t\t? {\n\t\t\t/** The response object of the fetch */\n\t\t\tresponse: Response;\n\t\t\t/** Typed result of response.json() */\n\t\t\tdata: GetResponseBody<ResolveTemplatePath<Path>, ChosenMethod, 200>;\n\t\t}\n\t\t: never\n\t: error extends false\n\t\t? {\n\t\t\t/** The response object of the fetch */\n\t\t\tresponse: Response;\n\t\t\t/** Typed result of response.json() or eventual error data */\n\t\t\tdata: GetResponseBody<ResolveTemplatePath<Path>, ChosenMethod, 200>;\n\t\t\t/** Wether the fetch errored */\n\t\t\terror: false;\n\t\t}\n\t\t: {\n\t\t\t/** The response object of the fetch */\n\t\t\tresponse: Response;\n\t\t\t/** Typed result of response.json() or eventual error data */\n\t\t\tdata:RiotErrorData | undefined;\n\t\t\t/** Wether the fetch errored */\n\t\t\terror: true;\n\t\t};\n\n/**\n * Options for the createRiotFetch functions\n * @template FetchOptions Options the fetch function can accept\n * @template ThrowOnError We set throwOnResponseError as a generic literal boolean, so that we can better type it\n */\nexport interface CreateRiotFetchOptions<FetchOptions, ThrowOnError extends boolean> {\n\t/** The Api Key obtained from Riot Games */\n\tapiKey: string\n\t/** fetch function that gets called (default: `undici.fetch`) */\n\tfetchFn?: (request: string, fetchOptions: FetchOptions) => Promise<Response>\n\t/** Function for dynamically creating the base url based on the given region. (default: standard riot api) */\n\tbaseUrl?: (region: string) => string,\n\t/**\n\t * Wether on 4xx/5xx response status the fetch should error or set error = true and include eventual error data in data\n\t * @see RiotError\n\t */\n\tthrowOnResponseError?: ThrowOnError,\n}\n\n/**\n * Basic Fetch Options that are essential for the functioning of createRiotFetch\n */\nexport interface BaseFetchOptions {\n\tmethod?: HTTPMethods,\n\theaders?: Headers,\n}\n\n/**\n * Creates a new function that basically wraps the provided fetch function to provide type information.\n *\n * @param {CreateRiotFetchOptions} createRiotFetchOptions Options for the createRiotFetch function\n * @param defaultOptions Options that get passed to the fetch function by default\n * @returns A fetch function to get fetch the Riot Games API type-safe\n */\nexport function createRiotFetch<\n\tFetchOptions extends BaseFetchOptions & Record<string, unknown>,\n\tThrowOnError extends boolean = false\n>(\n\t{\n\t\tapiKey,\n\t\tfetchFn = fetch,\n\t\tbaseUrl = (region: string) => `https://${region}.api.riotgames.com/`,\n\t\tthrowOnResponseError = false as ThrowOnError\n\t}: CreateRiotFetchOptions<FetchOptions & { body?: BodyInit }, ThrowOnError>,\n\tdefaultOptions: FetchOptions = {} as FetchOptions\n) {\n\tconst headers = new Headers(defaultOptions.headers);\n\theaders.append('X-Riot-Token', apiKey);\n\theaders.append('Content-Type', 'application/json');\n\tdefaultOptions.headers = headers;\n\n\t/**\n\t * A functions that can be used to fetch the Riot Games API with already defined defaults and type information\n\t * based on it's OpenAPI specification.\n\t *\n\t * @template Path The literal type of the path, inferred by `request`\n\t * @template UsableMethods All Methods that can be selected, used to autocomplete `method`\n\t * @template ChosenMethod The method\n\t * @param request The path of the resource requested. Gets merged using `URL`\n\t * @returns Response Object, a promise for the return body, depending on Path, Method and Status Code and an error indicator\n\t * @throws { RiotError } if `throwOnResponseError = true` and !response.ok\n\t */\n\treturn async <\n\t\tPath extends TemplatePaths,\n\t\tUsableMethods extends Methods<ResolveTemplatePath<Path>>,\n\t\tChosenMethod extends UsableMethods | undefined = 'get' extends UsableMethods ? 'get' : UsableMethods,\n\t>(\n\t\trequest: Path,\n\t\toptions: FetchOptions & {\n\t\t\tregion: GetSubdomain<ResolveTemplatePath<Path>>,\n\t\t\tmethod?: UsableMethods,\n\t\t}\n\t\t\t& GetRequestBody<ResolveTemplatePath<Path>, Extract<ChosenMethod, HTTPMethods>>\n\t\t\t& GetQuery<ResolveTemplatePath<Path>, Extract<ChosenMethod, HTTPMethods>>,\n\t) => {\n\t\tconst baseURL = baseUrl(options.region);\n\t\tlet req = new URL(request, baseURL).toString();\n\t\tif (options.query) {\n\t\t\tconst query = Object.entries(options.query).map(([key, value]) => [key, String(value)]);\n\t\t\treq += new URLSearchParams(query).toString();\n\t\t}\n\n\t\tconst response = await fetchFn(req, {\n\t\t\t...defaultOptions,\n\t\t\t...options,\n\t\t\tbody: JSON.stringify(options.body)\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst riotErrorData = await response.json()\n\t\t\t\t.then(obj => isRiotErrorData(obj) ? obj : undefined)\n\t\t\t\t.catch(() => undefined);\n\n\n\t\t\tif (throwOnResponseError) {\n\t\t\t\tthrow new RiotError(\n\t\t\t\t\t'Riot Games Fetch Error',\n\t\t\t\t\tresponse.status,\n\t\t\t\t\triotErrorData\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tresponse,\n\t\t\t\tdata: riotErrorData,\n\t\t\t\terror: true,\n\t\t\t} as RiotFetchReturn<Path, Extract<ChosenMethod, HTTPMethods>, ThrowOnError, true>;\n\t\t}\n\n\t\treturn {\n\t\t\tresponse,\n\t\t\tdata: await response.json() as GetResponseBody<ResolveTemplatePath<Path>, Extract<ChosenMethod, HTTPMethods>, 200>,\n\t\t\terror: false,\n\t\t} as RiotFetchReturn<Path, Extract<ChosenMethod, HTTPMethods>, ThrowOnError, false>;\n\t};\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmKO,IAAM,YAAN,cAAwB,MAAM;AAAA,EACpC,YAAY,SAAiB,YAAoB,MAAsB;AACtE,UAAM,OAAO;AACb,SAAK,aAAa;AAClB,SAAK,OAAO;AAAA,EACb;AAAA,EACA;AAAA,EACA;AACD;AASA,SAAS,gBAAgB,KAAoC;AAC5D,MAAI,OAAO,QAAQ,YAAY,QAAQ,KAAM,QAAO;AAEpD,QAAM,OAAO;AAEb,MAAI,KAAK,WAAW,QAAW;AAC9B,QAAI,OAAO,KAAK,WAAW,UAAU;AACpC,aAAO;AAAA,IACR;AAEA,QAAI,iBAAiB,KAAK,UAAU,OAAO,KAAK,OAAO,gBAAgB,UAAW;AACjF,aAAO;AAAA,IACR;AAEA,QAAI,aAAa,KAAK,UAAU,OAAO,KAAK,OAAO,YAAY,UAAW;AACzE,aAAO;AAAA,IACR;AAAA,EACD;AAEA,SAAO;AACR;AA6EO,SAAS,gBAIf;AAAA,EACC;AAAA,EACA,UAAU;AAAA,EACV,UAAU,CAAC,WAAmB,WAAW,MAAM;AAAA,EAC/C,uBAAuB;AACxB,GACA,iBAA+B,CAAC,GAC/B;AACD,QAAM,UAAU,IAAI,QAAQ,eAAe,OAAO;AAClD,UAAQ,OAAO,gBAAgB,MAAM;AACrC,UAAQ,OAAO,gBAAgB,kBAAkB;AACjD,iBAAe,UAAU;AAazB,SAAO,OAKN,SACA,YAMI;AACJ,UAAM,UAAU,QAAQ,QAAQ,MAAM;AACtC,QAAI,MAAM,IAAI,IAAI,SAAS,OAAO,EAAE,SAAS;AAC7C,QAAI,QAAQ,OAAO;AAClB,YAAM,QAAQ,OAAO,QAAQ,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,OAAO,KAAK,CAAC,CAAC;AACtF,aAAO,IAAI,gBAAgB,KAAK,EAAE,SAAS;AAAA,IAC5C;AAEA,UAAM,WAAW,MAAM,QAAQ,KAAK;AAAA,MACnC,GAAG;AAAA,MACH,GAAG;AAAA,MACH,MAAM,KAAK,UAAU,QAAQ,IAAI;AAAA,IAClC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AACjB,YAAM,gBAAgB,MAAM,SAAS,KAAK,EACxC,KAAK,SAAO,gBAAgB,GAAG,IAAI,MAAM,MAAS,EAClD,MAAM,MAAM,MAAS;AAGvB,UAAI,sBAAsB;AACzB,cAAM,IAAI;AAAA,UACT;AAAA,UACA,SAAS;AAAA,UACT;AAAA,QACD;AAAA,MACD;AAEA,aAAO;AAAA,QACN;AAAA,QACA,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA,IACD;AAEA,WAAO;AAAA,MACN;AAAA,MACA,MAAM,MAAM,SAAS,KAAK;AAAA,MAC1B,OAAO;AAAA,IACR;AAAA,EACD;AACD;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { paths, components } from './types/openapi.d.js';\n\nexport * from './types/openapi.d.js';\n\n\n/** Every possible API path, based on the OpenAPI document */\nexport type Paths = keyof paths;\n\n/**\n * Type util that replaces all occurences of curly brackets pairs in a string literal type to string placeholders,\n * resulting in a template literal type. For that it recursively tests the string for curly bracket pairs.\n *\n * @example TemplatifyPath<'summoner/{summonerName}/ranked'> -> `summoner/${string}/ranked`\n */\nexport type TemplatifyPathRecursive<Path extends string> =\n\tPath extends `${infer Start}/{${string}}${infer End}`\n\t\t? `${Start}/${string}${TemplatifyPathRecursive<End>}`\n\t\t: Path;\n\n\n/** Every possible API path, but templatified */\nexport type TemplatePaths = TemplatifyPathRecursive<Paths>;\n\n/** Splits a Path by `/` into an array */\nexport type SplitPathRecursive<Path extends string> = Path extends `${infer Head}/${infer Tail}`\n\t? [Head, ...SplitPathRecursive<Tail>]\n\t: [Path];\n\nexport type SplitPath<Path extends string> =\n Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}/${infer F}/${infer G}/${infer H}/${infer I}`\n \t? [A, B, C, D, E, F, G, H, I]\n \t: Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}/${infer F}/${infer G}/${infer H}`\n \t\t? [A, B, C, D, E, F, G, H]\n \t\t: Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}/${infer F}/${infer G}`\n \t\t\t? [A, B, C, D, E, F, G]\n \t\t\t: Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}/${infer F}`\n \t\t\t\t? [A, B, C, D, E, F]\n \t\t\t\t: Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}`\n \t\t\t\t\t? [A, B, C, D, E]\n \t\t\t\t\t: Path extends `${infer A}/${infer B}/${infer C}/${infer D}`\n \t\t\t\t\t\t? [A, B, C, D]\n \t\t\t\t\t\t: Path extends `${infer A}/${infer B}/${infer C}`\n \t\t\t\t\t\t\t? [A, B, C]\n \t\t\t\t\t\t\t: Path extends `${infer A}/${infer B}`\n \t\t\t\t\t\t\t\t? [A, B]\n \t\t\t\t\t\t\t\t: [Path];\n\n/**\n * Compares two splitted paths.\n *\n * Type is true if both splitted paths have the same length and every segment of Concrete extends its corresponding segment Template\n * */\nexport type MatchSegmentsRecursive<Template extends string[], Concrete extends string[]> =\n Template extends [infer TemplateSegment, ...infer TemplateRest]\n \t? Concrete extends [infer ConcreteSegment, ...infer ConcreteRest]\n \t\t? ConcreteSegment extends TemplateSegment\n \t\t\t? TemplateRest extends string[]\n \t\t\t\t? ConcreteRest extends string[]\n \t\t\t\t\t? MatchSegmentsRecursive<TemplateRest, ConcreteRest>\n \t\t\t\t\t: never\n \t\t\t\t: never\n \t\t\t: false\n \t\t: Concrete extends []\n \t\t\t? Template extends []\n \t\t\t\t? true\n \t\t\t\t: false\n \t\t\t: false\n \t: Template extends []\n \t\t? Concrete extends []\n \t\t\t? true\n \t\t\t: false\n \t\t: false;\n\nexport type MatchSegments<\n\tT extends [string?, string?, string?, string?, string?, string?, string?, string?, string?],\n\tC extends [string?, string?, string?, string?, string?, string?, string?, string?, string?]\n> =\n T['length'] extends C['length'] ? (\n \tC[0] extends T[0] ?\n \t\tC[1] extends T[1] ?\n \t\t\tC[2] extends T[2] ?\n \t\t\t\tC[3] extends T[3] ?\n \t\t\t\t\tC[4] extends T[4] ?\n \t\t\t\t\t\tC[5] extends T[5] ?\n \t\t\t\t\t\t\tC[6] extends T[6] ?\n \t\t\t\t\t\t\t\tC[7] extends T[7] ?\n \t\t\t\t\t\t\t\t\tC[8] extends T[8] ?\n \t\t\t\t\t\t\t\t\t\ttrue :\n \t\t\t\t\t\t\t\t\t\tfalse :\n \t\t\t\t\t\t\t\t\tfalse :\n \t\t\t\t\t\t\t\tfalse :\n \t\t\t\t\t\t\tfalse :\n \t\t\t\t\t\tfalse :\n \t\t\t\t\tfalse :\n \t\t\t\tfalse :\n \t\t\tfalse :\n \t\tfalse\n )\n \t: false;\n\n/**\n * Gives all API Paths that matches the path. Basically the reverse operation of TemplatifyPath\n *\n * @example ResolveTemplatePath<`/riot/account/v1/accounts/by-puuid/${string}`>\n * -> \"/riot/account/v1/accounts/by-puuid/{puuid}\"\n *\n * @example ResolveTemplatePath<`/riot/account/v1/accounts/by-riot-id/gameName/gameTag`>\n * -> \"/riot/account/v1/accounts/by-riot-id/{gameName}/{tagLine}\"\n */\nexport type ResolveTemplatePath<Path extends TemplatePaths> = {\n\t[P in Paths]: MatchSegments<SplitPath<TemplatifyPathRecursive<P>>, SplitPath<Path>> extends true ? P : never\n}[Paths];\n\nexport type HTTPMethods = 'get' | 'put' | 'post' | 'delete' | 'options' | 'head' | 'patch' | 'trace';\n\n/**\n * Get all available methods for a specific API path\n */\nexport type Methods<Path extends Paths> = Exclude<keyof {\n\t[K in keyof paths[Path] as paths[Path][K] extends undefined ? never : K]: paths[Path][K]\n}, 'parameters'>;\n\n/** Get all possible responses for a specific API path and method */\nexport type GetResponses<Path extends Paths, Method extends Methods<Path>> =\n\tpaths[Path][Method] extends { responses: infer Responses }\n\t\t? Responses\n\t\t: never;\n\n\n/** Get the response body for a specific API path, method and status code */\nexport type GetResponseBody<Path extends Paths, Method extends Methods<Path>, StatusCode extends number> =\n\tGetResponses<Path, Method> extends Record<StatusCode, { content?: { 'application/json': infer Body } }>\n\t\t? Body\n\t\t: never;\n\n\nexport type GetRequestBody<Path extends Paths, Method extends Methods<Path>> =\n paths[Path][Method] extends { requestBody?: never }\n \t? { body?: never }\n \t: paths[Path][Method] extends { requestBody: { content: { 'application/json': infer U } } }\n \t\t? { body: U }\n \t\t: paths[Path][Method] extends { requestBody?: { content: { 'application/json': infer U } } }\n \t\t\t? { body?: U }\n \t\t\t: unknown;\n\n\n/** Get the query parameters for a specific API path and method */\nexport type GetQuery<Path extends Paths, Method extends Methods<Path>> = Pick<paths[Path][Method]['parameters'], 'query'>;\n\n/** Regions for /riot/account/ endpoints */\nexport type AccountRegion = 'americas' | 'asia' | 'europe';\n/** Regions for some lol and tft endpoints */\nexport type LolRegion = 'br1' | 'eun1' | 'euw1' | 'jp1' | 'kr' | 'la1' | 'la2' | 'me1' | 'na1' | 'oc1' | 'ph2' | 'ru' | 'sg2' | 'th2' | 'tr1' | 'tw2' | 'vn2';\n/** Regions for lol and tft matches endpoints */\nexport type MatchRegion = 'americas' | 'asia' | 'europe' | 'sea';\n/** Regions for /lor/ endpoints */\nexport type LorRegion = 'americas' | 'europe' | 'sea';\n/** Regions for /val/ endpoints */\nexport type ValorantRegion = 'ap' | 'br' | 'eu' | 'latam' | 'na' | 'esports' | 'kr';\n\n\n/** Get the relevant subdomains, depending on the endpoint */\n// i dont like eslint indenting here\n/* eslint-disable @stylistic/indent */\nexport type GetSubdomain<Path extends TemplatePaths> =\n\tPath extends `/riot/account/${string}` ? AccountRegion :\n\tPath extends `/lol/champion-mastery/${string}` ? LolRegion :\n\tPath extends `/lol/platform/${string}` ? LolRegion :\n\tPath extends `/lol/clash/${string}` ? LolRegion :\n\tPath extends `/lol/league-exp/${string}` ? LolRegion :\n\tPath extends `/lol/league/${string}` ? LolRegion :\n\tPath extends `/lol/challenges/${string}` ? LolRegion :\n\tPath extends `/lol/rso-match/${string}` ? MatchRegion :\n\tPath extends `/lol/status/${string}` ? LolRegion :\n\tPath extends `/lor/deck/${string}` ? LorRegion :\n\tPath extends `/lor/inventory/${string}` ? LorRegion :\n\tPath extends `/lor/match/${string}` ? LorRegion | 'apac' :\n\tPath extends `/lor/ranked/${string}` ? LorRegion :\n\tPath extends `/lor/status/${string}` ? LorRegion :\n\tPath extends `/lol/match/${string}` ? MatchRegion :\n\tPath extends `/lol/spectator/${string}` ? LolRegion :\n\tPath extends `/fulfillment/${string}` ? LolRegion :\n\tPath extends `/lol/summoner/${string}` ? LolRegion :\n\tPath extends `/tft/league/${string}` ? LolRegion :\n\tPath extends `/tft/match/${string}` ? MatchRegion | 'esports' | 'esportseu' :\n\tPath extends `/tft/status/${string}` ? LolRegion :\n\tPath extends `/tft/summoner/${string}` ? LolRegion :\n\t// seems like only americas but not sure\n\tPath extends `/lol/tournament-stub/${string}` ? 'americas' :\n\t// don't know, can't see in api reference\n\tPath extends `/lol/tournament/${string}` ? LolRegion | MatchRegion :\n\t// The api docs do not include all regions for console, but for stability we will just include them\n\tPath extends `/val/match/console/${string}` ? ValorantRegion :\n\tPath extends `/val/console/ranked/${string}` ? ValorantRegion :\n\tPath extends `/val/content/${string}` ? ValorantRegion :\n\tPath extends `/val/match/${string}` ? ValorantRegion :\n\tPath extends `/val/ranked/${string}` ? ValorantRegion :\n\tPath extends `/val/status/${string}` ? Exclude<ValorantRegion, 'esports'>\n\t: never;\n/* eslint-enable @stylistic/indent */\n\n/** Typical structure for a RiotError json object. */\nexport type RiotErrorData = components['schemas']['Error'];\n\n/**\n * Error Class for a 4xx/5xx response code in a fetch to the Riot API\n */\nexport class RiotError extends Error {\n\tconstructor(message: string, statusCode: number, data?: RiotErrorData) {\n\t\tsuper(message);\n\t\tthis.statusCode = statusCode;\n\t\tthis.data = data;\n\t}\n\tstatusCode: number;\n\tdata: RiotErrorData | undefined;\n}\n\n/**\n * Type guard to check if an object is in the form of an riot error.\n * The API may return a structure like that on error, but we cannot be sure.\n *\n * @param obj obj to be checked\n * @returns true if obj has the form of RiotErroData\n */\nfunction isRiotErrorData(obj: unknown): obj is RiotErrorData {\n\tif (typeof obj !== 'object' || obj === null) return false;\n\n\tconst data = obj as RiotErrorData;\n\n\tif (data.status !== undefined) {\n\t\tif (typeof data.status !== 'object') {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ('status_code' in data.status && typeof data.status.status_code !== 'number')\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tif ('message' in data.status && typeof data.status.message !== 'string')\t\t{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n\n/**\n * This is a mess. I am sorry for this type abonimation.\n *\n * @template Path the Path of the API route\n * @template ChosenMethod the Method that is chosen, has to be one of the available methods of the Path\n * @template ThrowOnError Wether createRiotFetch is configured to throw on http errors or not\n * @template error response.ok, used for type narrowing\n */\nexport type RiotFetchReturn<\n\tPath extends TemplatePaths,\n\tChosenMethod extends Methods<ResolveTemplatePath<Path>>,\n\tThrowOnError extends boolean,\n\terror extends boolean,\n> = ThrowOnError extends true\n\t? error extends false\n\t\t? {\n\t\t\t/** The response object of the fetch */\n\t\t\tresponse: Response;\n\t\t\t/** Typed result of response.json() */\n\t\t\tdata: GetResponseBody<ResolveTemplatePath<Path>, ChosenMethod, 200>;\n\t\t}\n\t\t: never\n\t: error extends false\n\t\t? {\n\t\t\t/** The response object of the fetch */\n\t\t\tresponse: Response;\n\t\t\t/** Typed result of response.json() or eventual error data */\n\t\t\tdata: GetResponseBody<ResolveTemplatePath<Path>, ChosenMethod, 200>;\n\t\t\t/** Wether the fetch errored */\n\t\t\terror: false;\n\t\t}\n\t\t: {\n\t\t\t/** The response object of the fetch */\n\t\t\tresponse: Response;\n\t\t\t/** Typed result of response.json() or eventual error data */\n\t\t\tdata:RiotErrorData | undefined;\n\t\t\t/** Wether the fetch errored */\n\t\t\terror: true;\n\t\t};\n\n/**\n * Options for the createRiotFetch functions\n * @template FetchOptions Options the fetch function can accept\n * @template ThrowOnError We set throwOnResponseError as a generic literal boolean, so that we can better type it\n */\nexport interface CreateRiotFetchOptions<FetchOptions, ThrowOnError extends boolean> {\n\t/** The Api Key obtained from Riot Games */\n\tapiKey: string\n\t/** fetch function that gets called (default: `undici.fetch`) */\n\tfetchFn?: (request: string, fetchOptions: FetchOptions) => Promise<Response>\n\t/** Function for dynamically creating the base url based on the given region. (default: standard riot api) */\n\tbaseUrl?: (region: string) => string,\n\t/**\n\t * Wether on 4xx/5xx response status the fetch should error or set error = true and include eventual error data in data\n\t * @see RiotError\n\t */\n\tthrowOnResponseError?: ThrowOnError,\n}\n\n/**\n * Basic Fetch Options that are essential for the functioning of createRiotFetch\n */\nexport interface BaseFetchOptions {\n\tmethod?: HTTPMethods,\n\theaders?: Headers,\n}\n\n/**\n * Creates a new function that basically wraps the provided fetch function to provide type information.\n *\n * @param {CreateRiotFetchOptions} createRiotFetchOptions Options for the createRiotFetch function\n * @param defaultOptions Options that get passed to the fetch function by default\n * @returns A fetch function to get fetch the Riot Games API type-safe\n */\nexport function createRiotFetch<\n\tFetchOptions extends BaseFetchOptions & Record<string, unknown>,\n\tThrowOnError extends boolean = false\n>(\n\t{\n\t\tapiKey,\n\t\tfetchFn = fetch,\n\t\tbaseUrl = (region: string) => `https://${region}.api.riotgames.com/`,\n\t\tthrowOnResponseError = false as ThrowOnError\n\t}: CreateRiotFetchOptions<FetchOptions & { body?: BodyInit }, ThrowOnError>,\n\tdefaultOptions: FetchOptions = {} as FetchOptions\n) {\n\tconst headers = new Headers(defaultOptions.headers);\n\theaders.append('X-Riot-Token', apiKey);\n\theaders.append('Content-Type', 'application/json');\n\tdefaultOptions.headers = headers;\n\n\t/**\n\t * A functions that can be used to fetch the Riot Games API with already defined defaults and type information\n\t * based on it's OpenAPI specification.\n\t *\n\t * @template Path The literal type of the path, inferred by `request`\n\t * @template UsableMethods All Methods that can be selected, used to autocomplete `method`\n\t * @template ChosenMethod The method\n\t * @param request The path of the resource requested. Gets merged using `URL`\n\t * @returns Response Object, a promise for the return body, depending on Path, Method and Status Code and an error indicator\n\t * @throws { RiotError } if `throwOnResponseError = true` and !response.ok\n\t */\n\treturn async <\n\t\tPath extends TemplatePaths,\n\t\tUsableMethods extends Methods<ResolveTemplatePath<Path>>,\n\t\tChosenMethod extends UsableMethods | undefined = 'get' extends UsableMethods ? 'get' : UsableMethods,\n\t>(\n\t\trequest: Path,\n\t\toptions: FetchOptions & {\n\t\t\tregion: GetSubdomain<ResolveTemplatePath<Path>>,\n\t\t\tmethod?: UsableMethods,\n\t\t}\n\t\t\t& GetRequestBody<ResolveTemplatePath<Path>, Extract<ChosenMethod, HTTPMethods>>\n\t\t\t& GetQuery<ResolveTemplatePath<Path>, Extract<ChosenMethod, HTTPMethods>>,\n\t): Promise<\n\tRiotFetchReturn<Path, Extract<ChosenMethod, HTTPMethods>, ThrowOnError, true>\n\t|\tRiotFetchReturn<Path, Extract<ChosenMethod, HTTPMethods>, ThrowOnError, false>\n\t> => {\n\t\tconst baseURL = baseUrl(options.region);\n\t\tlet req = new URL(request, baseURL).toString();\n\t\tif (options.query) {\n\t\t\tconst query = Object.entries(options.query).map(([key, value]) => [key, String(value)]);\n\t\t\treq += new URLSearchParams(query).toString();\n\t\t}\n\n\t\tconst response = await fetchFn(req, {\n\t\t\t...defaultOptions,\n\t\t\t...options,\n\t\t\tbody: JSON.stringify(options.body)\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst riotErrorData = await response.json()\n\t\t\t\t.then(obj => isRiotErrorData(obj) ? obj : undefined)\n\t\t\t\t.catch(() => undefined);\n\n\n\t\t\tif (throwOnResponseError) {\n\t\t\t\tthrow new RiotError(\n\t\t\t\t\t'Riot Games Fetch Error',\n\t\t\t\t\tresponse.status,\n\t\t\t\t\triotErrorData\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tresponse,\n\t\t\t\tdata: riotErrorData,\n\t\t\t\terror: true,\n\t\t\t} as RiotFetchReturn<Path, Extract<ChosenMethod, HTTPMethods>, ThrowOnError, true>;\n\t\t}\n\n\t\treturn {\n\t\t\tresponse,\n\t\t\tdata: await response.json() as GetResponseBody<ResolveTemplatePath<Path>, Extract<ChosenMethod, HTTPMethods>, 200>,\n\t\t\terror: false,\n\t\t} as RiotFetchReturn<Path, Extract<ChosenMethod, HTTPMethods>, ThrowOnError, false>;\n\t};\n}\n\nexport const Queues = {\n\tCUSTOM: 0,\n\tHEXAKILL: 75,\n\tURF: [76, 1900],\n\tAR_URF: 900,\n\tARAM: {\n\t\tBUTCHERS_BRIDGE: 100,\n\t\tHOWLING_ABYSS: 450,\n\t\tALL: [100, 450]\n\t},\n\tALL_RANDOM: 325,\n\tBLIND: 430,\n\tDRAFT: 400,\n\tQUICKPLAY: 490,\n\tRANKED_SOLO: 420,\n\tRANKED_FLEX: 440,\n\tCLASH: {\n\t\tSUMMONERS_RIFT: 700,\n\t\tHOWLING_ABYSS: 720,\n\t\tARAM: 720,\n\t\tALL: [700, 720]\n\t},\n\tCOOP_VS_AI: {\n\t\tINTRO: 870,\n\t\tBEGINNER: 880,\n\t\tINTERMEDIATE: 890,\n\t\tALL: [870, 880, 890],\n\t},\n\tDOOM_BOTS: 960,\n\tONE_FOR_ALL: 1020,\n\tNEXUS_BLITZ: 1300,\n\tSPELLBOOK: 1400,\n\tARENA: [1700, 1710],\n\tSWARM: [1810, 1820, 1830, 1840],\n\tTUTORIAL: [2000, 2010, 2020]\n} as const;"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA+MO,IAAM,YAAN,cAAwB,MAAM;AAAA,EACpC,YAAY,SAAiB,YAAoB,MAAsB;AACtE,UAAM,OAAO;AACb,SAAK,aAAa;AAClB,SAAK,OAAO;AAAA,EACb;AAAA,EACA;AAAA,EACA;AACD;AASA,SAAS,gBAAgB,KAAoC;AAC5D,MAAI,OAAO,QAAQ,YAAY,QAAQ,KAAM,QAAO;AAEpD,QAAM,OAAO;AAEb,MAAI,KAAK,WAAW,QAAW;AAC9B,QAAI,OAAO,KAAK,WAAW,UAAU;AACpC,aAAO;AAAA,IACR;AAEA,QAAI,iBAAiB,KAAK,UAAU,OAAO,KAAK,OAAO,gBAAgB,UAAW;AACjF,aAAO;AAAA,IACR;AAEA,QAAI,aAAa,KAAK,UAAU,OAAO,KAAK,OAAO,YAAY,UAAW;AACzE,aAAO;AAAA,IACR;AAAA,EACD;AAEA,SAAO;AACR;AA6EO,SAAS,gBAIf;AAAA,EACC;AAAA,EACA,UAAU;AAAA,EACV,UAAU,CAAC,WAAmB,WAAW,MAAM;AAAA,EAC/C,uBAAuB;AACxB,GACA,iBAA+B,CAAC,GAC/B;AACD,QAAM,UAAU,IAAI,QAAQ,eAAe,OAAO;AAClD,UAAQ,OAAO,gBAAgB,MAAM;AACrC,UAAQ,OAAO,gBAAgB,kBAAkB;AACjD,iBAAe,UAAU;AAazB,SAAO,OAKN,SACA,YASI;AACJ,UAAM,UAAU,QAAQ,QAAQ,MAAM;AACtC,QAAI,MAAM,IAAI,IAAI,SAAS,OAAO,EAAE,SAAS;AAC7C,QAAI,QAAQ,OAAO;AAClB,YAAM,QAAQ,OAAO,QAAQ,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,OAAO,KAAK,CAAC,CAAC;AACtF,aAAO,IAAI,gBAAgB,KAAK,EAAE,SAAS;AAAA,IAC5C;AAEA,UAAM,WAAW,MAAM,QAAQ,KAAK;AAAA,MACnC,GAAG;AAAA,MACH,GAAG;AAAA,MACH,MAAM,KAAK,UAAU,QAAQ,IAAI;AAAA,IAClC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AACjB,YAAM,gBAAgB,MAAM,SAAS,KAAK,EACxC,KAAK,SAAO,gBAAgB,GAAG,IAAI,MAAM,MAAS,EAClD,MAAM,MAAM,MAAS;AAGvB,UAAI,sBAAsB;AACzB,cAAM,IAAI;AAAA,UACT;AAAA,UACA,SAAS;AAAA,UACT;AAAA,QACD;AAAA,MACD;AAEA,aAAO;AAAA,QACN;AAAA,QACA,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA,IACD;AAEA,WAAO;AAAA,MACN;AAAA,MACA,MAAM,MAAM,SAAS,KAAK;AAAA,MAC1B,OAAO;AAAA,IACR;AAAA,EACD;AACD;AAEO,IAAM,SAAS;AAAA,EACrB,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,KAAK,CAAC,IAAI,IAAI;AAAA,EACd,QAAQ;AAAA,EACR,MAAM;AAAA,IACL,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,KAAK,CAAC,KAAK,GAAG;AAAA,EACf;AAAA,EACA,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,OAAO;AAAA,EACP,WAAW;AAAA,EACX,aAAa;AAAA,EACb,aAAa;AAAA,EACb,OAAO;AAAA,IACN,gBAAgB;AAAA,IAChB,eAAe;AAAA,IACf,MAAM;AAAA,IACN,KAAK,CAAC,KAAK,GAAG;AAAA,EACf;AAAA,EACA,YAAY;AAAA,IACX,OAAO;AAAA,IACP,UAAU;AAAA,IACV,cAAc;AAAA,IACd,KAAK,CAAC,KAAK,KAAK,GAAG;AAAA,EACpB;AAAA,EACA,WAAW;AAAA,EACX,aAAa;AAAA,EACb,aAAa;AAAA,EACb,WAAW;AAAA,EACX,OAAO,CAAC,MAAM,IAAI;AAAA,EAClB,OAAO,CAAC,MAAM,MAAM,MAAM,IAAI;AAAA,EAC9B,UAAU,CAAC,KAAM,MAAM,IAAI;AAC5B;","names":[]}
package/dist/index.d.cts CHANGED
@@ -13475,17 +13475,19 @@ type Paths = keyof paths;
13475
13475
  *
13476
13476
  * @example TemplatifyPath<'summoner/{summonerName}/ranked'> -> `summoner/${string}/ranked`
13477
13477
  */
13478
- type TemplatifyPath<Path extends string> = Path extends `${infer Start}/{${string}}${infer End}` ? `${Start}/${string}${TemplatifyPath<End>}` : Path;
13478
+ type TemplatifyPathRecursive<Path extends string> = Path extends `${infer Start}/{${string}}${infer End}` ? `${Start}/${string}${TemplatifyPathRecursive<End>}` : Path;
13479
13479
  /** Every possible API path, but templatified */
13480
- type TemplatePaths = TemplatifyPath<Paths>;
13480
+ type TemplatePaths = TemplatifyPathRecursive<Paths>;
13481
13481
  /** Splits a Path by `/` into an array */
13482
- type SplitPath<Path extends string> = Path extends `${infer Head}/${infer Tail}` ? [Head, ...SplitPath<Tail>] : [Path];
13482
+ type SplitPathRecursive<Path extends string> = Path extends `${infer Head}/${infer Tail}` ? [Head, ...SplitPathRecursive<Tail>] : [Path];
13483
+ type SplitPath<Path extends string> = Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}/${infer F}/${infer G}/${infer H}/${infer I}` ? [A, B, C, D, E, F, G, H, I] : Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}/${infer F}/${infer G}/${infer H}` ? [A, B, C, D, E, F, G, H] : Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}/${infer F}/${infer G}` ? [A, B, C, D, E, F, G] : Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}/${infer F}` ? [A, B, C, D, E, F] : Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}` ? [A, B, C, D, E] : Path extends `${infer A}/${infer B}/${infer C}/${infer D}` ? [A, B, C, D] : Path extends `${infer A}/${infer B}/${infer C}` ? [A, B, C] : Path extends `${infer A}/${infer B}` ? [A, B] : [Path];
13483
13484
  /**
13484
13485
  * Compares two splitted paths.
13485
13486
  *
13486
13487
  * Type is true if both splitted paths have the same length and every segment of Concrete extends its corresponding segment Template
13487
13488
  * */
13488
- type MatchSegments<Template extends string[], Concrete extends string[]> = Template extends [infer TemplateSegment, ...infer TemplateRest] ? Concrete extends [infer ConcreteSegment, ...infer ConcreteRest] ? ConcreteSegment extends TemplateSegment ? TemplateRest extends string[] ? ConcreteRest extends string[] ? MatchSegments<TemplateRest, ConcreteRest> : never : never : false : Concrete extends [] ? Template extends [] ? true : false : false : Template extends [] ? Concrete extends [] ? true : false : false;
13489
+ type MatchSegmentsRecursive<Template extends string[], Concrete extends string[]> = Template extends [infer TemplateSegment, ...infer TemplateRest] ? Concrete extends [infer ConcreteSegment, ...infer ConcreteRest] ? ConcreteSegment extends TemplateSegment ? TemplateRest extends string[] ? ConcreteRest extends string[] ? MatchSegmentsRecursive<TemplateRest, ConcreteRest> : never : never : false : Concrete extends [] ? Template extends [] ? true : false : false : Template extends [] ? Concrete extends [] ? true : false : false;
13490
+ type MatchSegments<T extends [string?, string?, string?, string?, string?, string?, string?, string?, string?], C extends [string?, string?, string?, string?, string?, string?, string?, string?, string?]> = T['length'] extends C['length'] ? (C[0] extends T[0] ? C[1] extends T[1] ? C[2] extends T[2] ? C[3] extends T[3] ? C[4] extends T[4] ? C[5] extends T[5] ? C[6] extends T[6] ? C[7] extends T[7] ? C[8] extends T[8] ? true : false : false : false : false : false : false : false : false : false) : false;
13489
13491
  /**
13490
13492
  * Gives all API Paths that matches the path. Basically the reverse operation of TemplatifyPath
13491
13493
  *
@@ -13496,7 +13498,7 @@ type MatchSegments<Template extends string[], Concrete extends string[]> = Templ
13496
13498
  * -> "/riot/account/v1/accounts/by-riot-id/{gameName}/{tagLine}"
13497
13499
  */
13498
13500
  type ResolveTemplatePath<Path extends TemplatePaths> = {
13499
- [P in Paths]: MatchSegments<SplitPath<TemplatifyPath<P>>, SplitPath<Path>> extends true ? P : never;
13501
+ [P in Paths]: MatchSegments<SplitPath<TemplatifyPathRecursive<P>>, SplitPath<Path>> extends true ? P : never;
13500
13502
  }[Paths];
13501
13503
  type HTTPMethods = 'get' | 'put' | 'post' | 'delete' | 'options' | 'head' | 'patch' | 'trace';
13502
13504
  /**
@@ -13626,5 +13628,41 @@ declare function createRiotFetch<FetchOptions extends BaseFetchOptions & Record<
13626
13628
  region: GetSubdomain<ResolveTemplatePath<Path>>;
13627
13629
  method?: UsableMethods;
13628
13630
  } & GetRequestBody<ResolveTemplatePath<Path>, Extract<ChosenMethod, HTTPMethods>> & GetQuery<ResolveTemplatePath<Path>, Extract<ChosenMethod, HTTPMethods>>) => Promise<RiotFetchReturn<Path, Extract<ChosenMethod, HTTPMethods>, ThrowOnError, true> | RiotFetchReturn<Path, Extract<ChosenMethod, HTTPMethods>, ThrowOnError, false>>;
13631
+ declare const Queues: {
13632
+ readonly CUSTOM: 0;
13633
+ readonly HEXAKILL: 75;
13634
+ readonly URF: readonly [76, 1900];
13635
+ readonly AR_URF: 900;
13636
+ readonly ARAM: {
13637
+ readonly BUTCHERS_BRIDGE: 100;
13638
+ readonly HOWLING_ABYSS: 450;
13639
+ readonly ALL: readonly [100, 450];
13640
+ };
13641
+ readonly ALL_RANDOM: 325;
13642
+ readonly BLIND: 430;
13643
+ readonly DRAFT: 400;
13644
+ readonly QUICKPLAY: 490;
13645
+ readonly RANKED_SOLO: 420;
13646
+ readonly RANKED_FLEX: 440;
13647
+ readonly CLASH: {
13648
+ readonly SUMMONERS_RIFT: 700;
13649
+ readonly HOWLING_ABYSS: 720;
13650
+ readonly ARAM: 720;
13651
+ readonly ALL: readonly [700, 720];
13652
+ };
13653
+ readonly COOP_VS_AI: {
13654
+ readonly INTRO: 870;
13655
+ readonly BEGINNER: 880;
13656
+ readonly INTERMEDIATE: 890;
13657
+ readonly ALL: readonly [870, 880, 890];
13658
+ };
13659
+ readonly DOOM_BOTS: 960;
13660
+ readonly ONE_FOR_ALL: 1020;
13661
+ readonly NEXUS_BLITZ: 1300;
13662
+ readonly SPELLBOOK: 1400;
13663
+ readonly ARENA: readonly [1700, 1710];
13664
+ readonly SWARM: readonly [1810, 1820, 1830, 1840];
13665
+ readonly TUTORIAL: readonly [2000, 2010, 2020];
13666
+ };
13629
13667
 
13630
- export { type $defs, type AccountRegion, type BaseFetchOptions, type CreateRiotFetchOptions, type GetQuery, type GetRequestBody, type GetResponseBody, type GetResponses, type GetSubdomain, type HTTPMethods, type LolRegion, type LorRegion, type MatchRegion, type MatchSegments, type Methods, type Paths, type ResolveTemplatePath, RiotError, type RiotErrorData, type RiotFetchReturn, type SplitPath, type TemplatePaths, type TemplatifyPath, type ValorantRegion, type components, createRiotFetch, type operations, type paths, type webhooks };
13668
+ export { type $defs, type AccountRegion, type BaseFetchOptions, type CreateRiotFetchOptions, type GetQuery, type GetRequestBody, type GetResponseBody, type GetResponses, type GetSubdomain, type HTTPMethods, type LolRegion, type LorRegion, type MatchRegion, type MatchSegments, type MatchSegmentsRecursive, type Methods, type Paths, Queues, type ResolveTemplatePath, RiotError, type RiotErrorData, type RiotFetchReturn, type SplitPath, type SplitPathRecursive, type TemplatePaths, type TemplatifyPathRecursive, type ValorantRegion, type components, createRiotFetch, type operations, type paths, type webhooks };
package/dist/index.d.ts CHANGED
@@ -13475,17 +13475,19 @@ type Paths = keyof paths;
13475
13475
  *
13476
13476
  * @example TemplatifyPath<'summoner/{summonerName}/ranked'> -> `summoner/${string}/ranked`
13477
13477
  */
13478
- type TemplatifyPath<Path extends string> = Path extends `${infer Start}/{${string}}${infer End}` ? `${Start}/${string}${TemplatifyPath<End>}` : Path;
13478
+ type TemplatifyPathRecursive<Path extends string> = Path extends `${infer Start}/{${string}}${infer End}` ? `${Start}/${string}${TemplatifyPathRecursive<End>}` : Path;
13479
13479
  /** Every possible API path, but templatified */
13480
- type TemplatePaths = TemplatifyPath<Paths>;
13480
+ type TemplatePaths = TemplatifyPathRecursive<Paths>;
13481
13481
  /** Splits a Path by `/` into an array */
13482
- type SplitPath<Path extends string> = Path extends `${infer Head}/${infer Tail}` ? [Head, ...SplitPath<Tail>] : [Path];
13482
+ type SplitPathRecursive<Path extends string> = Path extends `${infer Head}/${infer Tail}` ? [Head, ...SplitPathRecursive<Tail>] : [Path];
13483
+ type SplitPath<Path extends string> = Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}/${infer F}/${infer G}/${infer H}/${infer I}` ? [A, B, C, D, E, F, G, H, I] : Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}/${infer F}/${infer G}/${infer H}` ? [A, B, C, D, E, F, G, H] : Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}/${infer F}/${infer G}` ? [A, B, C, D, E, F, G] : Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}/${infer F}` ? [A, B, C, D, E, F] : Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}` ? [A, B, C, D, E] : Path extends `${infer A}/${infer B}/${infer C}/${infer D}` ? [A, B, C, D] : Path extends `${infer A}/${infer B}/${infer C}` ? [A, B, C] : Path extends `${infer A}/${infer B}` ? [A, B] : [Path];
13483
13484
  /**
13484
13485
  * Compares two splitted paths.
13485
13486
  *
13486
13487
  * Type is true if both splitted paths have the same length and every segment of Concrete extends its corresponding segment Template
13487
13488
  * */
13488
- type MatchSegments<Template extends string[], Concrete extends string[]> = Template extends [infer TemplateSegment, ...infer TemplateRest] ? Concrete extends [infer ConcreteSegment, ...infer ConcreteRest] ? ConcreteSegment extends TemplateSegment ? TemplateRest extends string[] ? ConcreteRest extends string[] ? MatchSegments<TemplateRest, ConcreteRest> : never : never : false : Concrete extends [] ? Template extends [] ? true : false : false : Template extends [] ? Concrete extends [] ? true : false : false;
13489
+ type MatchSegmentsRecursive<Template extends string[], Concrete extends string[]> = Template extends [infer TemplateSegment, ...infer TemplateRest] ? Concrete extends [infer ConcreteSegment, ...infer ConcreteRest] ? ConcreteSegment extends TemplateSegment ? TemplateRest extends string[] ? ConcreteRest extends string[] ? MatchSegmentsRecursive<TemplateRest, ConcreteRest> : never : never : false : Concrete extends [] ? Template extends [] ? true : false : false : Template extends [] ? Concrete extends [] ? true : false : false;
13490
+ type MatchSegments<T extends [string?, string?, string?, string?, string?, string?, string?, string?, string?], C extends [string?, string?, string?, string?, string?, string?, string?, string?, string?]> = T['length'] extends C['length'] ? (C[0] extends T[0] ? C[1] extends T[1] ? C[2] extends T[2] ? C[3] extends T[3] ? C[4] extends T[4] ? C[5] extends T[5] ? C[6] extends T[6] ? C[7] extends T[7] ? C[8] extends T[8] ? true : false : false : false : false : false : false : false : false : false) : false;
13489
13491
  /**
13490
13492
  * Gives all API Paths that matches the path. Basically the reverse operation of TemplatifyPath
13491
13493
  *
@@ -13496,7 +13498,7 @@ type MatchSegments<Template extends string[], Concrete extends string[]> = Templ
13496
13498
  * -> "/riot/account/v1/accounts/by-riot-id/{gameName}/{tagLine}"
13497
13499
  */
13498
13500
  type ResolveTemplatePath<Path extends TemplatePaths> = {
13499
- [P in Paths]: MatchSegments<SplitPath<TemplatifyPath<P>>, SplitPath<Path>> extends true ? P : never;
13501
+ [P in Paths]: MatchSegments<SplitPath<TemplatifyPathRecursive<P>>, SplitPath<Path>> extends true ? P : never;
13500
13502
  }[Paths];
13501
13503
  type HTTPMethods = 'get' | 'put' | 'post' | 'delete' | 'options' | 'head' | 'patch' | 'trace';
13502
13504
  /**
@@ -13626,5 +13628,41 @@ declare function createRiotFetch<FetchOptions extends BaseFetchOptions & Record<
13626
13628
  region: GetSubdomain<ResolveTemplatePath<Path>>;
13627
13629
  method?: UsableMethods;
13628
13630
  } & GetRequestBody<ResolveTemplatePath<Path>, Extract<ChosenMethod, HTTPMethods>> & GetQuery<ResolveTemplatePath<Path>, Extract<ChosenMethod, HTTPMethods>>) => Promise<RiotFetchReturn<Path, Extract<ChosenMethod, HTTPMethods>, ThrowOnError, true> | RiotFetchReturn<Path, Extract<ChosenMethod, HTTPMethods>, ThrowOnError, false>>;
13631
+ declare const Queues: {
13632
+ readonly CUSTOM: 0;
13633
+ readonly HEXAKILL: 75;
13634
+ readonly URF: readonly [76, 1900];
13635
+ readonly AR_URF: 900;
13636
+ readonly ARAM: {
13637
+ readonly BUTCHERS_BRIDGE: 100;
13638
+ readonly HOWLING_ABYSS: 450;
13639
+ readonly ALL: readonly [100, 450];
13640
+ };
13641
+ readonly ALL_RANDOM: 325;
13642
+ readonly BLIND: 430;
13643
+ readonly DRAFT: 400;
13644
+ readonly QUICKPLAY: 490;
13645
+ readonly RANKED_SOLO: 420;
13646
+ readonly RANKED_FLEX: 440;
13647
+ readonly CLASH: {
13648
+ readonly SUMMONERS_RIFT: 700;
13649
+ readonly HOWLING_ABYSS: 720;
13650
+ readonly ARAM: 720;
13651
+ readonly ALL: readonly [700, 720];
13652
+ };
13653
+ readonly COOP_VS_AI: {
13654
+ readonly INTRO: 870;
13655
+ readonly BEGINNER: 880;
13656
+ readonly INTERMEDIATE: 890;
13657
+ readonly ALL: readonly [870, 880, 890];
13658
+ };
13659
+ readonly DOOM_BOTS: 960;
13660
+ readonly ONE_FOR_ALL: 1020;
13661
+ readonly NEXUS_BLITZ: 1300;
13662
+ readonly SPELLBOOK: 1400;
13663
+ readonly ARENA: readonly [1700, 1710];
13664
+ readonly SWARM: readonly [1810, 1820, 1830, 1840];
13665
+ readonly TUTORIAL: readonly [2000, 2010, 2020];
13666
+ };
13629
13667
 
13630
- export { type $defs, type AccountRegion, type BaseFetchOptions, type CreateRiotFetchOptions, type GetQuery, type GetRequestBody, type GetResponseBody, type GetResponses, type GetSubdomain, type HTTPMethods, type LolRegion, type LorRegion, type MatchRegion, type MatchSegments, type Methods, type Paths, type ResolveTemplatePath, RiotError, type RiotErrorData, type RiotFetchReturn, type SplitPath, type TemplatePaths, type TemplatifyPath, type ValorantRegion, type components, createRiotFetch, type operations, type paths, type webhooks };
13668
+ export { type $defs, type AccountRegion, type BaseFetchOptions, type CreateRiotFetchOptions, type GetQuery, type GetRequestBody, type GetResponseBody, type GetResponses, type GetSubdomain, type HTTPMethods, type LolRegion, type LorRegion, type MatchRegion, type MatchSegments, type MatchSegmentsRecursive, type Methods, type Paths, Queues, type ResolveTemplatePath, RiotError, type RiotErrorData, type RiotFetchReturn, type SplitPath, type SplitPathRecursive, type TemplatePaths, type TemplatifyPathRecursive, type ValorantRegion, type components, createRiotFetch, type operations, type paths, type webhooks };
package/dist/index.js CHANGED
@@ -68,7 +68,44 @@ function createRiotFetch({
68
68
  };
69
69
  };
70
70
  }
71
+ var Queues = {
72
+ CUSTOM: 0,
73
+ HEXAKILL: 75,
74
+ URF: [76, 1900],
75
+ AR_URF: 900,
76
+ ARAM: {
77
+ BUTCHERS_BRIDGE: 100,
78
+ HOWLING_ABYSS: 450,
79
+ ALL: [100, 450]
80
+ },
81
+ ALL_RANDOM: 325,
82
+ BLIND: 430,
83
+ DRAFT: 400,
84
+ QUICKPLAY: 490,
85
+ RANKED_SOLO: 420,
86
+ RANKED_FLEX: 440,
87
+ CLASH: {
88
+ SUMMONERS_RIFT: 700,
89
+ HOWLING_ABYSS: 720,
90
+ ARAM: 720,
91
+ ALL: [700, 720]
92
+ },
93
+ COOP_VS_AI: {
94
+ INTRO: 870,
95
+ BEGINNER: 880,
96
+ INTERMEDIATE: 890,
97
+ ALL: [870, 880, 890]
98
+ },
99
+ DOOM_BOTS: 960,
100
+ ONE_FOR_ALL: 1020,
101
+ NEXUS_BLITZ: 1300,
102
+ SPELLBOOK: 1400,
103
+ ARENA: [1700, 1710],
104
+ SWARM: [1810, 1820, 1830, 1840],
105
+ TUTORIAL: [2e3, 2010, 2020]
106
+ };
71
107
  export {
108
+ Queues,
72
109
  RiotError,
73
110
  createRiotFetch
74
111
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { paths, components } from './types/openapi.d.js';\n\nexport * from './types/openapi.d.js';\n\n\n/** Every possible API path, based on the OpenAPI document */\nexport type Paths = keyof paths;\n\n/**\n * Type util that replaces all occurences of curly brackets pairs in a string literal type to string placeholders,\n * resulting in a template literal type. For that it recursively tests the string for curly bracket pairs.\n *\n * @example TemplatifyPath<'summoner/{summonerName}/ranked'> -> `summoner/${string}/ranked`\n */\nexport type TemplatifyPath<Path extends string> =\n\tPath extends `${infer Start}/{${string}}${infer End}`\n\t\t? `${Start}/${string}${TemplatifyPath<End>}`\n\t\t: Path;\n\n\n/** Every possible API path, but templatified */\nexport type TemplatePaths = TemplatifyPath<Paths>;\n\n/** Splits a Path by `/` into an array */\nexport type SplitPath<Path extends string> = Path extends `${infer Head}/${infer Tail}`\n\t? [Head, ...SplitPath<Tail>]\n\t: [Path];\n\n/**\n * Compares two splitted paths.\n *\n * Type is true if both splitted paths have the same length and every segment of Concrete extends its corresponding segment Template\n * */\nexport type MatchSegments<Template extends string[], Concrete extends string[]> =\n Template extends [infer TemplateSegment, ...infer TemplateRest]\n \t? Concrete extends [infer ConcreteSegment, ...infer ConcreteRest]\n \t\t? ConcreteSegment extends TemplateSegment\n \t\t\t? TemplateRest extends string[]\n \t\t\t\t? ConcreteRest extends string[]\n \t\t\t\t\t? MatchSegments<TemplateRest, ConcreteRest>\n \t\t\t\t\t: never\n \t\t\t\t: never\n \t\t\t: false\n \t\t: Concrete extends []\n \t\t\t? Template extends []\n \t\t\t\t? true\n \t\t\t\t: false\n \t\t\t: false\n \t: Template extends []\n \t\t? Concrete extends []\n \t\t\t? true\n \t\t\t: false\n \t\t: false;\n\n/**\n * Gives all API Paths that matches the path. Basically the reverse operation of TemplatifyPath\n *\n * @example ResolveTemplatePath<`/riot/account/v1/accounts/by-puuid/${string}`>\n * -> \"/riot/account/v1/accounts/by-puuid/{puuid}\"\n *\n * @example ResolveTemplatePath<`/riot/account/v1/accounts/by-riot-id/gameName/gameTag`>\n * -> \"/riot/account/v1/accounts/by-riot-id/{gameName}/{tagLine}\"\n */\nexport type ResolveTemplatePath<Path extends TemplatePaths> = {\n\t[P in Paths]: MatchSegments<SplitPath<TemplatifyPath<P>>, SplitPath<Path>> extends true ? P : never\n}[Paths];\n\nexport type HTTPMethods = 'get' | 'put' | 'post' | 'delete' | 'options' | 'head' | 'patch' | 'trace';\n\n/**\n * Get all available methods for a specific API path\n */\nexport type Methods<Path extends Paths> = Exclude<keyof {\n\t[K in keyof paths[Path] as paths[Path][K] extends undefined ? never : K]: paths[Path][K]\n}, 'parameters'>;\n\n/** Get all possible responses for a specific API path and method */\nexport type GetResponses<Path extends Paths, Method extends Methods<Path>> =\n\tpaths[Path][Method] extends { responses: infer Responses }\n\t\t? Responses\n\t\t: never;\n\n\n/** Get the response body for a specific API path, method and status code */\nexport type GetResponseBody<Path extends Paths, Method extends Methods<Path>, StatusCode extends number> =\n\tGetResponses<Path, Method> extends Record<StatusCode, { content?: { 'application/json': infer Body } }>\n\t\t? Body\n\t\t: never;\n\n\nexport type GetRequestBody<Path extends Paths, Method extends Methods<Path>> =\n paths[Path][Method] extends { requestBody?: never }\n \t? { body?: never }\n \t: paths[Path][Method] extends { requestBody: { content: { 'application/json': infer U } } }\n \t\t? { body: U }\n \t\t: paths[Path][Method] extends { requestBody?: { content: { 'application/json': infer U } } }\n \t\t\t? { body?: U }\n \t\t\t: unknown;\n\n\n/** Get the query parameters for a specific API path and method */\nexport type GetQuery<Path extends Paths, Method extends Methods<Path>> =\n Pick<paths[Path][Method]['parameters'], 'query'>;\n\n\n/** Regions for /riot/account/ endpoints */\nexport type AccountRegion = 'americas' | 'asia' | 'europe';\n/** Regions for some lol and tft endpoints */\nexport type LolRegion = 'br1' | 'eun1' | 'euw1' | 'jp1' | 'kr' | 'la1' | 'la2' | 'me1' | 'na1' | 'oc1' | 'ph2' | 'ru' | 'sg2' | 'th2' | 'tr1' | 'tw2' | 'vn2';\n/** Regions for lol and tft matches endpoints */\nexport type MatchRegion = 'americas' | 'asia' | 'europe' | 'sea';\n/** Regions for /lor/ endpoints */\nexport type LorRegion = 'americas' | 'europe' | 'sea';\n/** Regions for /val/ endpoints */\nexport type ValorantRegion = 'ap' | 'br' | 'eu' | 'latam' | 'na' | 'esports' | 'kr';\n\n\n/** Get the relevant subdomains, depending on the endpoint */\n// i dont like eslint indenting here\n/* eslint-disable @stylistic/indent */\nexport type GetSubdomain<Path extends TemplatePaths> =\n\tPath extends `/riot/account/${string}` ? AccountRegion :\n\tPath extends `/lol/champion-mastery/${string}` ? LolRegion :\n\tPath extends `/lol/platform/${string}` ? LolRegion :\n\tPath extends `/lol/clash/${string}` ? LolRegion :\n\tPath extends `/lol/league-exp/${string}` ? LolRegion :\n\tPath extends `/lol/league/${string}` ? LolRegion :\n\tPath extends `/lol/challenges/${string}` ? LolRegion :\n\tPath extends `/lol/rso-match/${string}` ? MatchRegion :\n\tPath extends `/lol/status/${string}` ? LolRegion :\n\tPath extends `/lor/deck/${string}` ? LorRegion :\n\tPath extends `/lor/inventory/${string}` ? LorRegion :\n\tPath extends `/lor/match/${string}` ? LorRegion | 'apac' :\n\tPath extends `/lor/ranked/${string}` ? LorRegion :\n\tPath extends `/lor/status/${string}` ? LorRegion :\n\tPath extends `/lol/match/${string}` ? MatchRegion :\n\tPath extends `/lol/spectator/${string}` ? LolRegion :\n\tPath extends `/fulfillment/${string}` ? LolRegion :\n\tPath extends `/lol/summoner/${string}` ? LolRegion :\n\tPath extends `/tft/league/${string}` ? LolRegion :\n\tPath extends `/tft/match/${string}` ? MatchRegion | 'esports' | 'esportseu' :\n\tPath extends `/tft/status/${string}` ? LolRegion :\n\tPath extends `/tft/summoner/${string}` ? LolRegion :\n\t// seems like only americas but not sure\n\tPath extends `/lol/tournament-stub/${string}` ? 'americas' :\n\t// don't know, can't see in api reference\n\tPath extends `/lol/tournament/${string}` ? LolRegion | MatchRegion :\n\t// The api docs do not include all regions for console, but for stability we will just include them\n\tPath extends `/val/match/console/${string}` ? ValorantRegion :\n\tPath extends `/val/console/ranked/${string}` ? ValorantRegion :\n\tPath extends `/val/content/${string}` ? ValorantRegion :\n\tPath extends `/val/match/${string}` ? ValorantRegion :\n\tPath extends `/val/ranked/${string}` ? ValorantRegion :\n\tPath extends `/val/status/${string}` ? Exclude<ValorantRegion, 'esports'>\n\t: never;\n/* eslint-enable @stylistic/indent */\n\n/** Typical structure for a RiotError json object. */\nexport type RiotErrorData = components['schemas']['Error'];\n\n/**\n * Error Class for a 4xx/5xx response code in a fetch to the Riot API\n */\nexport class RiotError extends Error {\n\tconstructor(message: string, statusCode: number, data?: RiotErrorData) {\n\t\tsuper(message);\n\t\tthis.statusCode = statusCode;\n\t\tthis.data = data;\n\t}\n\tstatusCode: number;\n\tdata: RiotErrorData | undefined;\n}\n\n/**\n * Type guard to check if an object is in the form of an riot error.\n * The API may return a structure like that on error, but we cannot be sure.\n *\n * @param obj obj to be checked\n * @returns true if obj has the form of RiotErroData\n */\nfunction isRiotErrorData(obj: unknown): obj is RiotErrorData {\n\tif (typeof obj !== 'object' || obj === null) return false;\n\n\tconst data = obj as RiotErrorData;\n\n\tif (data.status !== undefined) {\n\t\tif (typeof data.status !== 'object') {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ('status_code' in data.status && typeof data.status.status_code !== 'number')\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tif ('message' in data.status && typeof data.status.message !== 'string')\t\t{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n\n/**\n * This is a mess. I am sorry for this type abonimation.\n *\n * @template Path the Path of the API route\n * @template ChosenMethod the Method that is chosen, has to be one of the available methods of the Path\n * @template ThrowOnError Wether createRiotFetch is configured to throw on http errors or not\n * @template error response.ok, used for type narrowing\n */\nexport type RiotFetchReturn<\n\tPath extends TemplatePaths,\n\tChosenMethod extends Methods<ResolveTemplatePath<Path>>,\n\tThrowOnError extends boolean,\n\terror extends boolean,\n> = ThrowOnError extends true\n\t? error extends false\n\t\t? {\n\t\t\t/** The response object of the fetch */\n\t\t\tresponse: Response;\n\t\t\t/** Typed result of response.json() */\n\t\t\tdata: GetResponseBody<ResolveTemplatePath<Path>, ChosenMethod, 200>;\n\t\t}\n\t\t: never\n\t: error extends false\n\t\t? {\n\t\t\t/** The response object of the fetch */\n\t\t\tresponse: Response;\n\t\t\t/** Typed result of response.json() or eventual error data */\n\t\t\tdata: GetResponseBody<ResolveTemplatePath<Path>, ChosenMethod, 200>;\n\t\t\t/** Wether the fetch errored */\n\t\t\terror: false;\n\t\t}\n\t\t: {\n\t\t\t/** The response object of the fetch */\n\t\t\tresponse: Response;\n\t\t\t/** Typed result of response.json() or eventual error data */\n\t\t\tdata:RiotErrorData | undefined;\n\t\t\t/** Wether the fetch errored */\n\t\t\terror: true;\n\t\t};\n\n/**\n * Options for the createRiotFetch functions\n * @template FetchOptions Options the fetch function can accept\n * @template ThrowOnError We set throwOnResponseError as a generic literal boolean, so that we can better type it\n */\nexport interface CreateRiotFetchOptions<FetchOptions, ThrowOnError extends boolean> {\n\t/** The Api Key obtained from Riot Games */\n\tapiKey: string\n\t/** fetch function that gets called (default: `undici.fetch`) */\n\tfetchFn?: (request: string, fetchOptions: FetchOptions) => Promise<Response>\n\t/** Function for dynamically creating the base url based on the given region. (default: standard riot api) */\n\tbaseUrl?: (region: string) => string,\n\t/**\n\t * Wether on 4xx/5xx response status the fetch should error or set error = true and include eventual error data in data\n\t * @see RiotError\n\t */\n\tthrowOnResponseError?: ThrowOnError,\n}\n\n/**\n * Basic Fetch Options that are essential for the functioning of createRiotFetch\n */\nexport interface BaseFetchOptions {\n\tmethod?: HTTPMethods,\n\theaders?: Headers,\n}\n\n/**\n * Creates a new function that basically wraps the provided fetch function to provide type information.\n *\n * @param {CreateRiotFetchOptions} createRiotFetchOptions Options for the createRiotFetch function\n * @param defaultOptions Options that get passed to the fetch function by default\n * @returns A fetch function to get fetch the Riot Games API type-safe\n */\nexport function createRiotFetch<\n\tFetchOptions extends BaseFetchOptions & Record<string, unknown>,\n\tThrowOnError extends boolean = false\n>(\n\t{\n\t\tapiKey,\n\t\tfetchFn = fetch,\n\t\tbaseUrl = (region: string) => `https://${region}.api.riotgames.com/`,\n\t\tthrowOnResponseError = false as ThrowOnError\n\t}: CreateRiotFetchOptions<FetchOptions & { body?: BodyInit }, ThrowOnError>,\n\tdefaultOptions: FetchOptions = {} as FetchOptions\n) {\n\tconst headers = new Headers(defaultOptions.headers);\n\theaders.append('X-Riot-Token', apiKey);\n\theaders.append('Content-Type', 'application/json');\n\tdefaultOptions.headers = headers;\n\n\t/**\n\t * A functions that can be used to fetch the Riot Games API with already defined defaults and type information\n\t * based on it's OpenAPI specification.\n\t *\n\t * @template Path The literal type of the path, inferred by `request`\n\t * @template UsableMethods All Methods that can be selected, used to autocomplete `method`\n\t * @template ChosenMethod The method\n\t * @param request The path of the resource requested. Gets merged using `URL`\n\t * @returns Response Object, a promise for the return body, depending on Path, Method and Status Code and an error indicator\n\t * @throws { RiotError } if `throwOnResponseError = true` and !response.ok\n\t */\n\treturn async <\n\t\tPath extends TemplatePaths,\n\t\tUsableMethods extends Methods<ResolveTemplatePath<Path>>,\n\t\tChosenMethod extends UsableMethods | undefined = 'get' extends UsableMethods ? 'get' : UsableMethods,\n\t>(\n\t\trequest: Path,\n\t\toptions: FetchOptions & {\n\t\t\tregion: GetSubdomain<ResolveTemplatePath<Path>>,\n\t\t\tmethod?: UsableMethods,\n\t\t}\n\t\t\t& GetRequestBody<ResolveTemplatePath<Path>, Extract<ChosenMethod, HTTPMethods>>\n\t\t\t& GetQuery<ResolveTemplatePath<Path>, Extract<ChosenMethod, HTTPMethods>>,\n\t) => {\n\t\tconst baseURL = baseUrl(options.region);\n\t\tlet req = new URL(request, baseURL).toString();\n\t\tif (options.query) {\n\t\t\tconst query = Object.entries(options.query).map(([key, value]) => [key, String(value)]);\n\t\t\treq += new URLSearchParams(query).toString();\n\t\t}\n\n\t\tconst response = await fetchFn(req, {\n\t\t\t...defaultOptions,\n\t\t\t...options,\n\t\t\tbody: JSON.stringify(options.body)\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst riotErrorData = await response.json()\n\t\t\t\t.then(obj => isRiotErrorData(obj) ? obj : undefined)\n\t\t\t\t.catch(() => undefined);\n\n\n\t\t\tif (throwOnResponseError) {\n\t\t\t\tthrow new RiotError(\n\t\t\t\t\t'Riot Games Fetch Error',\n\t\t\t\t\tresponse.status,\n\t\t\t\t\triotErrorData\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tresponse,\n\t\t\t\tdata: riotErrorData,\n\t\t\t\terror: true,\n\t\t\t} as RiotFetchReturn<Path, Extract<ChosenMethod, HTTPMethods>, ThrowOnError, true>;\n\t\t}\n\n\t\treturn {\n\t\t\tresponse,\n\t\t\tdata: await response.json() as GetResponseBody<ResolveTemplatePath<Path>, Extract<ChosenMethod, HTTPMethods>, 200>,\n\t\t\terror: false,\n\t\t} as RiotFetchReturn<Path, Extract<ChosenMethod, HTTPMethods>, ThrowOnError, false>;\n\t};\n}"],"mappings":";AAmKO,IAAM,YAAN,cAAwB,MAAM;AAAA,EACpC,YAAY,SAAiB,YAAoB,MAAsB;AACtE,UAAM,OAAO;AACb,SAAK,aAAa;AAClB,SAAK,OAAO;AAAA,EACb;AAAA,EACA;AAAA,EACA;AACD;AASA,SAAS,gBAAgB,KAAoC;AAC5D,MAAI,OAAO,QAAQ,YAAY,QAAQ,KAAM,QAAO;AAEpD,QAAM,OAAO;AAEb,MAAI,KAAK,WAAW,QAAW;AAC9B,QAAI,OAAO,KAAK,WAAW,UAAU;AACpC,aAAO;AAAA,IACR;AAEA,QAAI,iBAAiB,KAAK,UAAU,OAAO,KAAK,OAAO,gBAAgB,UAAW;AACjF,aAAO;AAAA,IACR;AAEA,QAAI,aAAa,KAAK,UAAU,OAAO,KAAK,OAAO,YAAY,UAAW;AACzE,aAAO;AAAA,IACR;AAAA,EACD;AAEA,SAAO;AACR;AA6EO,SAAS,gBAIf;AAAA,EACC;AAAA,EACA,UAAU;AAAA,EACV,UAAU,CAAC,WAAmB,WAAW,MAAM;AAAA,EAC/C,uBAAuB;AACxB,GACA,iBAA+B,CAAC,GAC/B;AACD,QAAM,UAAU,IAAI,QAAQ,eAAe,OAAO;AAClD,UAAQ,OAAO,gBAAgB,MAAM;AACrC,UAAQ,OAAO,gBAAgB,kBAAkB;AACjD,iBAAe,UAAU;AAazB,SAAO,OAKN,SACA,YAMI;AACJ,UAAM,UAAU,QAAQ,QAAQ,MAAM;AACtC,QAAI,MAAM,IAAI,IAAI,SAAS,OAAO,EAAE,SAAS;AAC7C,QAAI,QAAQ,OAAO;AAClB,YAAM,QAAQ,OAAO,QAAQ,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,OAAO,KAAK,CAAC,CAAC;AACtF,aAAO,IAAI,gBAAgB,KAAK,EAAE,SAAS;AAAA,IAC5C;AAEA,UAAM,WAAW,MAAM,QAAQ,KAAK;AAAA,MACnC,GAAG;AAAA,MACH,GAAG;AAAA,MACH,MAAM,KAAK,UAAU,QAAQ,IAAI;AAAA,IAClC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AACjB,YAAM,gBAAgB,MAAM,SAAS,KAAK,EACxC,KAAK,SAAO,gBAAgB,GAAG,IAAI,MAAM,MAAS,EAClD,MAAM,MAAM,MAAS;AAGvB,UAAI,sBAAsB;AACzB,cAAM,IAAI;AAAA,UACT;AAAA,UACA,SAAS;AAAA,UACT;AAAA,QACD;AAAA,MACD;AAEA,aAAO;AAAA,QACN;AAAA,QACA,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA,IACD;AAEA,WAAO;AAAA,MACN;AAAA,MACA,MAAM,MAAM,SAAS,KAAK;AAAA,MAC1B,OAAO;AAAA,IACR;AAAA,EACD;AACD;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { paths, components } from './types/openapi.d.js';\n\nexport * from './types/openapi.d.js';\n\n\n/** Every possible API path, based on the OpenAPI document */\nexport type Paths = keyof paths;\n\n/**\n * Type util that replaces all occurences of curly brackets pairs in a string literal type to string placeholders,\n * resulting in a template literal type. For that it recursively tests the string for curly bracket pairs.\n *\n * @example TemplatifyPath<'summoner/{summonerName}/ranked'> -> `summoner/${string}/ranked`\n */\nexport type TemplatifyPathRecursive<Path extends string> =\n\tPath extends `${infer Start}/{${string}}${infer End}`\n\t\t? `${Start}/${string}${TemplatifyPathRecursive<End>}`\n\t\t: Path;\n\n\n/** Every possible API path, but templatified */\nexport type TemplatePaths = TemplatifyPathRecursive<Paths>;\n\n/** Splits a Path by `/` into an array */\nexport type SplitPathRecursive<Path extends string> = Path extends `${infer Head}/${infer Tail}`\n\t? [Head, ...SplitPathRecursive<Tail>]\n\t: [Path];\n\nexport type SplitPath<Path extends string> =\n Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}/${infer F}/${infer G}/${infer H}/${infer I}`\n \t? [A, B, C, D, E, F, G, H, I]\n \t: Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}/${infer F}/${infer G}/${infer H}`\n \t\t? [A, B, C, D, E, F, G, H]\n \t\t: Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}/${infer F}/${infer G}`\n \t\t\t? [A, B, C, D, E, F, G]\n \t\t\t: Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}/${infer F}`\n \t\t\t\t? [A, B, C, D, E, F]\n \t\t\t\t: Path extends `${infer A}/${infer B}/${infer C}/${infer D}/${infer E}`\n \t\t\t\t\t? [A, B, C, D, E]\n \t\t\t\t\t: Path extends `${infer A}/${infer B}/${infer C}/${infer D}`\n \t\t\t\t\t\t? [A, B, C, D]\n \t\t\t\t\t\t: Path extends `${infer A}/${infer B}/${infer C}`\n \t\t\t\t\t\t\t? [A, B, C]\n \t\t\t\t\t\t\t: Path extends `${infer A}/${infer B}`\n \t\t\t\t\t\t\t\t? [A, B]\n \t\t\t\t\t\t\t\t: [Path];\n\n/**\n * Compares two splitted paths.\n *\n * Type is true if both splitted paths have the same length and every segment of Concrete extends its corresponding segment Template\n * */\nexport type MatchSegmentsRecursive<Template extends string[], Concrete extends string[]> =\n Template extends [infer TemplateSegment, ...infer TemplateRest]\n \t? Concrete extends [infer ConcreteSegment, ...infer ConcreteRest]\n \t\t? ConcreteSegment extends TemplateSegment\n \t\t\t? TemplateRest extends string[]\n \t\t\t\t? ConcreteRest extends string[]\n \t\t\t\t\t? MatchSegmentsRecursive<TemplateRest, ConcreteRest>\n \t\t\t\t\t: never\n \t\t\t\t: never\n \t\t\t: false\n \t\t: Concrete extends []\n \t\t\t? Template extends []\n \t\t\t\t? true\n \t\t\t\t: false\n \t\t\t: false\n \t: Template extends []\n \t\t? Concrete extends []\n \t\t\t? true\n \t\t\t: false\n \t\t: false;\n\nexport type MatchSegments<\n\tT extends [string?, string?, string?, string?, string?, string?, string?, string?, string?],\n\tC extends [string?, string?, string?, string?, string?, string?, string?, string?, string?]\n> =\n T['length'] extends C['length'] ? (\n \tC[0] extends T[0] ?\n \t\tC[1] extends T[1] ?\n \t\t\tC[2] extends T[2] ?\n \t\t\t\tC[3] extends T[3] ?\n \t\t\t\t\tC[4] extends T[4] ?\n \t\t\t\t\t\tC[5] extends T[5] ?\n \t\t\t\t\t\t\tC[6] extends T[6] ?\n \t\t\t\t\t\t\t\tC[7] extends T[7] ?\n \t\t\t\t\t\t\t\t\tC[8] extends T[8] ?\n \t\t\t\t\t\t\t\t\t\ttrue :\n \t\t\t\t\t\t\t\t\t\tfalse :\n \t\t\t\t\t\t\t\t\tfalse :\n \t\t\t\t\t\t\t\tfalse :\n \t\t\t\t\t\t\tfalse :\n \t\t\t\t\t\tfalse :\n \t\t\t\t\tfalse :\n \t\t\t\tfalse :\n \t\t\tfalse :\n \t\tfalse\n )\n \t: false;\n\n/**\n * Gives all API Paths that matches the path. Basically the reverse operation of TemplatifyPath\n *\n * @example ResolveTemplatePath<`/riot/account/v1/accounts/by-puuid/${string}`>\n * -> \"/riot/account/v1/accounts/by-puuid/{puuid}\"\n *\n * @example ResolveTemplatePath<`/riot/account/v1/accounts/by-riot-id/gameName/gameTag`>\n * -> \"/riot/account/v1/accounts/by-riot-id/{gameName}/{tagLine}\"\n */\nexport type ResolveTemplatePath<Path extends TemplatePaths> = {\n\t[P in Paths]: MatchSegments<SplitPath<TemplatifyPathRecursive<P>>, SplitPath<Path>> extends true ? P : never\n}[Paths];\n\nexport type HTTPMethods = 'get' | 'put' | 'post' | 'delete' | 'options' | 'head' | 'patch' | 'trace';\n\n/**\n * Get all available methods for a specific API path\n */\nexport type Methods<Path extends Paths> = Exclude<keyof {\n\t[K in keyof paths[Path] as paths[Path][K] extends undefined ? never : K]: paths[Path][K]\n}, 'parameters'>;\n\n/** Get all possible responses for a specific API path and method */\nexport type GetResponses<Path extends Paths, Method extends Methods<Path>> =\n\tpaths[Path][Method] extends { responses: infer Responses }\n\t\t? Responses\n\t\t: never;\n\n\n/** Get the response body for a specific API path, method and status code */\nexport type GetResponseBody<Path extends Paths, Method extends Methods<Path>, StatusCode extends number> =\n\tGetResponses<Path, Method> extends Record<StatusCode, { content?: { 'application/json': infer Body } }>\n\t\t? Body\n\t\t: never;\n\n\nexport type GetRequestBody<Path extends Paths, Method extends Methods<Path>> =\n paths[Path][Method] extends { requestBody?: never }\n \t? { body?: never }\n \t: paths[Path][Method] extends { requestBody: { content: { 'application/json': infer U } } }\n \t\t? { body: U }\n \t\t: paths[Path][Method] extends { requestBody?: { content: { 'application/json': infer U } } }\n \t\t\t? { body?: U }\n \t\t\t: unknown;\n\n\n/** Get the query parameters for a specific API path and method */\nexport type GetQuery<Path extends Paths, Method extends Methods<Path>> = Pick<paths[Path][Method]['parameters'], 'query'>;\n\n/** Regions for /riot/account/ endpoints */\nexport type AccountRegion = 'americas' | 'asia' | 'europe';\n/** Regions for some lol and tft endpoints */\nexport type LolRegion = 'br1' | 'eun1' | 'euw1' | 'jp1' | 'kr' | 'la1' | 'la2' | 'me1' | 'na1' | 'oc1' | 'ph2' | 'ru' | 'sg2' | 'th2' | 'tr1' | 'tw2' | 'vn2';\n/** Regions for lol and tft matches endpoints */\nexport type MatchRegion = 'americas' | 'asia' | 'europe' | 'sea';\n/** Regions for /lor/ endpoints */\nexport type LorRegion = 'americas' | 'europe' | 'sea';\n/** Regions for /val/ endpoints */\nexport type ValorantRegion = 'ap' | 'br' | 'eu' | 'latam' | 'na' | 'esports' | 'kr';\n\n\n/** Get the relevant subdomains, depending on the endpoint */\n// i dont like eslint indenting here\n/* eslint-disable @stylistic/indent */\nexport type GetSubdomain<Path extends TemplatePaths> =\n\tPath extends `/riot/account/${string}` ? AccountRegion :\n\tPath extends `/lol/champion-mastery/${string}` ? LolRegion :\n\tPath extends `/lol/platform/${string}` ? LolRegion :\n\tPath extends `/lol/clash/${string}` ? LolRegion :\n\tPath extends `/lol/league-exp/${string}` ? LolRegion :\n\tPath extends `/lol/league/${string}` ? LolRegion :\n\tPath extends `/lol/challenges/${string}` ? LolRegion :\n\tPath extends `/lol/rso-match/${string}` ? MatchRegion :\n\tPath extends `/lol/status/${string}` ? LolRegion :\n\tPath extends `/lor/deck/${string}` ? LorRegion :\n\tPath extends `/lor/inventory/${string}` ? LorRegion :\n\tPath extends `/lor/match/${string}` ? LorRegion | 'apac' :\n\tPath extends `/lor/ranked/${string}` ? LorRegion :\n\tPath extends `/lor/status/${string}` ? LorRegion :\n\tPath extends `/lol/match/${string}` ? MatchRegion :\n\tPath extends `/lol/spectator/${string}` ? LolRegion :\n\tPath extends `/fulfillment/${string}` ? LolRegion :\n\tPath extends `/lol/summoner/${string}` ? LolRegion :\n\tPath extends `/tft/league/${string}` ? LolRegion :\n\tPath extends `/tft/match/${string}` ? MatchRegion | 'esports' | 'esportseu' :\n\tPath extends `/tft/status/${string}` ? LolRegion :\n\tPath extends `/tft/summoner/${string}` ? LolRegion :\n\t// seems like only americas but not sure\n\tPath extends `/lol/tournament-stub/${string}` ? 'americas' :\n\t// don't know, can't see in api reference\n\tPath extends `/lol/tournament/${string}` ? LolRegion | MatchRegion :\n\t// The api docs do not include all regions for console, but for stability we will just include them\n\tPath extends `/val/match/console/${string}` ? ValorantRegion :\n\tPath extends `/val/console/ranked/${string}` ? ValorantRegion :\n\tPath extends `/val/content/${string}` ? ValorantRegion :\n\tPath extends `/val/match/${string}` ? ValorantRegion :\n\tPath extends `/val/ranked/${string}` ? ValorantRegion :\n\tPath extends `/val/status/${string}` ? Exclude<ValorantRegion, 'esports'>\n\t: never;\n/* eslint-enable @stylistic/indent */\n\n/** Typical structure for a RiotError json object. */\nexport type RiotErrorData = components['schemas']['Error'];\n\n/**\n * Error Class for a 4xx/5xx response code in a fetch to the Riot API\n */\nexport class RiotError extends Error {\n\tconstructor(message: string, statusCode: number, data?: RiotErrorData) {\n\t\tsuper(message);\n\t\tthis.statusCode = statusCode;\n\t\tthis.data = data;\n\t}\n\tstatusCode: number;\n\tdata: RiotErrorData | undefined;\n}\n\n/**\n * Type guard to check if an object is in the form of an riot error.\n * The API may return a structure like that on error, but we cannot be sure.\n *\n * @param obj obj to be checked\n * @returns true if obj has the form of RiotErroData\n */\nfunction isRiotErrorData(obj: unknown): obj is RiotErrorData {\n\tif (typeof obj !== 'object' || obj === null) return false;\n\n\tconst data = obj as RiotErrorData;\n\n\tif (data.status !== undefined) {\n\t\tif (typeof data.status !== 'object') {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ('status_code' in data.status && typeof data.status.status_code !== 'number')\t\t{\n\t\t\treturn false;\n\t\t}\n\n\t\tif ('message' in data.status && typeof data.status.message !== 'string')\t\t{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n\n/**\n * This is a mess. I am sorry for this type abonimation.\n *\n * @template Path the Path of the API route\n * @template ChosenMethod the Method that is chosen, has to be one of the available methods of the Path\n * @template ThrowOnError Wether createRiotFetch is configured to throw on http errors or not\n * @template error response.ok, used for type narrowing\n */\nexport type RiotFetchReturn<\n\tPath extends TemplatePaths,\n\tChosenMethod extends Methods<ResolveTemplatePath<Path>>,\n\tThrowOnError extends boolean,\n\terror extends boolean,\n> = ThrowOnError extends true\n\t? error extends false\n\t\t? {\n\t\t\t/** The response object of the fetch */\n\t\t\tresponse: Response;\n\t\t\t/** Typed result of response.json() */\n\t\t\tdata: GetResponseBody<ResolveTemplatePath<Path>, ChosenMethod, 200>;\n\t\t}\n\t\t: never\n\t: error extends false\n\t\t? {\n\t\t\t/** The response object of the fetch */\n\t\t\tresponse: Response;\n\t\t\t/** Typed result of response.json() or eventual error data */\n\t\t\tdata: GetResponseBody<ResolveTemplatePath<Path>, ChosenMethod, 200>;\n\t\t\t/** Wether the fetch errored */\n\t\t\terror: false;\n\t\t}\n\t\t: {\n\t\t\t/** The response object of the fetch */\n\t\t\tresponse: Response;\n\t\t\t/** Typed result of response.json() or eventual error data */\n\t\t\tdata:RiotErrorData | undefined;\n\t\t\t/** Wether the fetch errored */\n\t\t\terror: true;\n\t\t};\n\n/**\n * Options for the createRiotFetch functions\n * @template FetchOptions Options the fetch function can accept\n * @template ThrowOnError We set throwOnResponseError as a generic literal boolean, so that we can better type it\n */\nexport interface CreateRiotFetchOptions<FetchOptions, ThrowOnError extends boolean> {\n\t/** The Api Key obtained from Riot Games */\n\tapiKey: string\n\t/** fetch function that gets called (default: `undici.fetch`) */\n\tfetchFn?: (request: string, fetchOptions: FetchOptions) => Promise<Response>\n\t/** Function for dynamically creating the base url based on the given region. (default: standard riot api) */\n\tbaseUrl?: (region: string) => string,\n\t/**\n\t * Wether on 4xx/5xx response status the fetch should error or set error = true and include eventual error data in data\n\t * @see RiotError\n\t */\n\tthrowOnResponseError?: ThrowOnError,\n}\n\n/**\n * Basic Fetch Options that are essential for the functioning of createRiotFetch\n */\nexport interface BaseFetchOptions {\n\tmethod?: HTTPMethods,\n\theaders?: Headers,\n}\n\n/**\n * Creates a new function that basically wraps the provided fetch function to provide type information.\n *\n * @param {CreateRiotFetchOptions} createRiotFetchOptions Options for the createRiotFetch function\n * @param defaultOptions Options that get passed to the fetch function by default\n * @returns A fetch function to get fetch the Riot Games API type-safe\n */\nexport function createRiotFetch<\n\tFetchOptions extends BaseFetchOptions & Record<string, unknown>,\n\tThrowOnError extends boolean = false\n>(\n\t{\n\t\tapiKey,\n\t\tfetchFn = fetch,\n\t\tbaseUrl = (region: string) => `https://${region}.api.riotgames.com/`,\n\t\tthrowOnResponseError = false as ThrowOnError\n\t}: CreateRiotFetchOptions<FetchOptions & { body?: BodyInit }, ThrowOnError>,\n\tdefaultOptions: FetchOptions = {} as FetchOptions\n) {\n\tconst headers = new Headers(defaultOptions.headers);\n\theaders.append('X-Riot-Token', apiKey);\n\theaders.append('Content-Type', 'application/json');\n\tdefaultOptions.headers = headers;\n\n\t/**\n\t * A functions that can be used to fetch the Riot Games API with already defined defaults and type information\n\t * based on it's OpenAPI specification.\n\t *\n\t * @template Path The literal type of the path, inferred by `request`\n\t * @template UsableMethods All Methods that can be selected, used to autocomplete `method`\n\t * @template ChosenMethod The method\n\t * @param request The path of the resource requested. Gets merged using `URL`\n\t * @returns Response Object, a promise for the return body, depending on Path, Method and Status Code and an error indicator\n\t * @throws { RiotError } if `throwOnResponseError = true` and !response.ok\n\t */\n\treturn async <\n\t\tPath extends TemplatePaths,\n\t\tUsableMethods extends Methods<ResolveTemplatePath<Path>>,\n\t\tChosenMethod extends UsableMethods | undefined = 'get' extends UsableMethods ? 'get' : UsableMethods,\n\t>(\n\t\trequest: Path,\n\t\toptions: FetchOptions & {\n\t\t\tregion: GetSubdomain<ResolveTemplatePath<Path>>,\n\t\t\tmethod?: UsableMethods,\n\t\t}\n\t\t\t& GetRequestBody<ResolveTemplatePath<Path>, Extract<ChosenMethod, HTTPMethods>>\n\t\t\t& GetQuery<ResolveTemplatePath<Path>, Extract<ChosenMethod, HTTPMethods>>,\n\t): Promise<\n\tRiotFetchReturn<Path, Extract<ChosenMethod, HTTPMethods>, ThrowOnError, true>\n\t|\tRiotFetchReturn<Path, Extract<ChosenMethod, HTTPMethods>, ThrowOnError, false>\n\t> => {\n\t\tconst baseURL = baseUrl(options.region);\n\t\tlet req = new URL(request, baseURL).toString();\n\t\tif (options.query) {\n\t\t\tconst query = Object.entries(options.query).map(([key, value]) => [key, String(value)]);\n\t\t\treq += new URLSearchParams(query).toString();\n\t\t}\n\n\t\tconst response = await fetchFn(req, {\n\t\t\t...defaultOptions,\n\t\t\t...options,\n\t\t\tbody: JSON.stringify(options.body)\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst riotErrorData = await response.json()\n\t\t\t\t.then(obj => isRiotErrorData(obj) ? obj : undefined)\n\t\t\t\t.catch(() => undefined);\n\n\n\t\t\tif (throwOnResponseError) {\n\t\t\t\tthrow new RiotError(\n\t\t\t\t\t'Riot Games Fetch Error',\n\t\t\t\t\tresponse.status,\n\t\t\t\t\triotErrorData\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tresponse,\n\t\t\t\tdata: riotErrorData,\n\t\t\t\terror: true,\n\t\t\t} as RiotFetchReturn<Path, Extract<ChosenMethod, HTTPMethods>, ThrowOnError, true>;\n\t\t}\n\n\t\treturn {\n\t\t\tresponse,\n\t\t\tdata: await response.json() as GetResponseBody<ResolveTemplatePath<Path>, Extract<ChosenMethod, HTTPMethods>, 200>,\n\t\t\terror: false,\n\t\t} as RiotFetchReturn<Path, Extract<ChosenMethod, HTTPMethods>, ThrowOnError, false>;\n\t};\n}\n\nexport const Queues = {\n\tCUSTOM: 0,\n\tHEXAKILL: 75,\n\tURF: [76, 1900],\n\tAR_URF: 900,\n\tARAM: {\n\t\tBUTCHERS_BRIDGE: 100,\n\t\tHOWLING_ABYSS: 450,\n\t\tALL: [100, 450]\n\t},\n\tALL_RANDOM: 325,\n\tBLIND: 430,\n\tDRAFT: 400,\n\tQUICKPLAY: 490,\n\tRANKED_SOLO: 420,\n\tRANKED_FLEX: 440,\n\tCLASH: {\n\t\tSUMMONERS_RIFT: 700,\n\t\tHOWLING_ABYSS: 720,\n\t\tARAM: 720,\n\t\tALL: [700, 720]\n\t},\n\tCOOP_VS_AI: {\n\t\tINTRO: 870,\n\t\tBEGINNER: 880,\n\t\tINTERMEDIATE: 890,\n\t\tALL: [870, 880, 890],\n\t},\n\tDOOM_BOTS: 960,\n\tONE_FOR_ALL: 1020,\n\tNEXUS_BLITZ: 1300,\n\tSPELLBOOK: 1400,\n\tARENA: [1700, 1710],\n\tSWARM: [1810, 1820, 1830, 1840],\n\tTUTORIAL: [2000, 2010, 2020]\n} as const;"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "riotapi-fetch-typed",
3
3
  "type": "module",
4
- "version": "1.1.3-dev",
4
+ "version": "1.2.0-dev",
5
5
  "description": "Fetch the Riot Games API with type safety, thanks to the OpenAPI specification.",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",