From d9a8ca2f2a70718a2af72609c9236fd5131bcb3d Mon Sep 17 00:00:00 2001 From: Pinta365 Date: Tue, 12 Sep 2023 20:02:55 +0200 Subject: [PATCH] updates to shared mods --- src/shared/auth.ts | 22 ++++++++--------- src/shared/config.ts | 8 +++++++ src/shared/errors.ts | 57 ++++++++++++++++++++++++++++++++++++++++++++ src/shared/types.ts | 30 ++++++++++++++++++----- 4 files changed, 99 insertions(+), 18 deletions(-) create mode 100644 src/shared/errors.ts diff --git a/src/shared/auth.ts b/src/shared/auth.ts index d14ef82..aff431c 100644 --- a/src/shared/auth.ts +++ b/src/shared/auth.ts @@ -1,4 +1,5 @@ -import { getSetup } from "./config.ts"; +import { getSetup, tokenUrl } from "./config.ts"; +import { AuthenticationError, MissingClientIdError, MissingClientSecretError } from "./errors.ts"; interface AuthConfig { accessToken: string; @@ -15,8 +16,12 @@ export function getauthConfig(): AuthConfig { } export async function authenticate(force = false) { - if (!getSetup().clientId || !getSetup().ClientSecret) { - throw new Error("clientId and ClientSecret must be set using setup() before calling authenticate."); + if (!getSetup().clientId) { + throw new MissingClientIdError(); + } + + if (!getSetup().ClientSecret) { + throw new MissingClientSecretError(); } if ( @@ -26,11 +31,7 @@ export async function authenticate(force = false) { return authConfig.accessToken; } - const url = getSetup().region === "cn" - ? "https://www.battlenet.com.cn/oauth/token" - : `https://${getSetup().region}.battle.net/oauth/token`; - - const response = await fetch(url, { + const response = await fetch(tokenUrl(getSetup().region), { method: "POST", headers: { "Authorization": "Basic " + btoa(`${getSetup().clientId}:${getSetup().ClientSecret}`), @@ -41,13 +42,10 @@ export async function authenticate(force = false) { if (response.ok) { const data = await response.json(); - - console.log("Auth successful"); authConfig.accessToken = data.access_token; authConfig.tokenExpiration = Date.now() + data.expires_in * 1000; return true; } else { - console.error("Auth failed:", response.status, response.statusText); - return false; + throw new AuthenticationError("Problem with Authentication", response.status, response.statusText); } } diff --git a/src/shared/config.ts b/src/shared/config.ts index 5cf228d..05d799a 100644 --- a/src/shared/config.ts +++ b/src/shared/config.ts @@ -14,6 +14,14 @@ let config: Config = { ClientSecret: "", }; +export function tokenUrl(region: Regions) { + return region === "cn" ? "https://www.battlenet.com.cn/oauth/token" : `https://${region}.battle.net/oauth/token`; +} + +export function apiBaseUrl(region: Regions) { + return region === "cn" ? "https://gateway.battlenet.com.cn" : `https://${region}.api.blizzard.com`; +} + export function setup(userConfig: Partial) { config = { ...config, ...userConfig }; } diff --git a/src/shared/errors.ts b/src/shared/errors.ts new file mode 100644 index 0000000..a30b978 --- /dev/null +++ b/src/shared/errors.ts @@ -0,0 +1,57 @@ +/** + * Custom error class representing an API error. + * @class + * @extends {Error} + */ +export class APIError extends Error { + statusCode: number; + responseBody: string; + + constructor(message: string, statusCode: number, responseBody: string) { + super(message); + this.name = "APIError"; + this.statusCode = statusCode; + this.responseBody = responseBody; + } +} + +/** + * Custom error class representing an Authentication error. + * @class + * @extends {Error} + */ +export class AuthenticationError extends Error { + statusCode: number; + responseBody: string; + + constructor(message: string, statusCode: number, responseBody: string) { + super(message); + this.name = "AuthenticationError"; + this.statusCode = statusCode; + this.responseBody = responseBody; + } +} + +/** + * Custom error class representing a missing client id error. + * @class + * @extends {Error} + */ +export class MissingClientIdError extends Error { + constructor() { + super("Client Id must be setup before calling authenticate. Check documentation"); + this.name = "MissingClientIdError"; + } +} + +/** + * Custom error class representing a missing client secret error. + * @class + * @extends {Error} + */ +export class MissingClientSecretError extends Error { + constructor() { + super("Client Secret must be setup before calling authenticate. Check documentation"); + this.name = "MissingClientSecretError"; + } +} diff --git a/src/shared/types.ts b/src/shared/types.ts index 896a0ea..b59b716 100644 --- a/src/shared/types.ts +++ b/src/shared/types.ts @@ -5,12 +5,6 @@ export interface requestOptions { qs?: Record; } -export interface LinkSelfHref { - self: { - href: string; - }; -} - export type Regions = "us" | "eu" | "kr" | "tw" | "cn"; export type Locales = @@ -30,5 +24,29 @@ export type Locales = export type Namespaces = "static" | "dynamic" | "profile"; +/** Self-referential link */ +export interface LinkSelfHref { + self: { + href: string; + }; +} +/** Represents a single string if localization was supplied in request or an object of localized key-value strings if not */ +export interface LocalizedString { + name: string | Record; +} +export interface KeyNameId { + key: { + href: string; + }; + name: LocalizedString; + id: number; +} + +export interface KeyId { + key: { + href: string; + }; + id: number; +}