mirror of
https://github.com/tribufu/sdk-js
synced 2025-06-16 18:44:18 +00:00
Create http wrapper
This commit is contained in:
126
src/api.ts
126
src/api.ts
@ -1,6 +1,6 @@
|
|||||||
// Copyright (c) Tribufu. All Rights Reserved.
|
// Copyright (c) Tribufu. All Rights Reserved.
|
||||||
|
|
||||||
import { HeaderMap } from "./http";
|
import { HeaderMap, TribufuHttp } from "./http";
|
||||||
import { JavaScriptRuntime } from "./node";
|
import { JavaScriptRuntime } from "./node";
|
||||||
import { TribufuApiOptions } from "./options";
|
import { TribufuApiOptions } from "./options";
|
||||||
import { TribufuBot } from "./bot";
|
import { TribufuBot } from "./bot";
|
||||||
@ -24,39 +24,17 @@ import snakecaseKeys from "snakecase-keys";
|
|||||||
* - A client give you read and write access to the Tribufu API as a client application.
|
* - A client give you read and write access to the Tribufu API as a client application.
|
||||||
*/
|
*/
|
||||||
export class TribufuApi {
|
export class TribufuApi {
|
||||||
|
protected readonly http: TribufuHttp;
|
||||||
protected readonly options: TribufuApiOptions;
|
protected readonly options: TribufuApiOptions;
|
||||||
protected readonly http: AxiosInstance;
|
|
||||||
|
|
||||||
constructor(options?: TribufuApiOptions | null) {
|
constructor(options?: TribufuApiOptions | null) {
|
||||||
this.options = options || {};
|
this.options = options || {};
|
||||||
|
|
||||||
let http = axios.create({
|
this.http = new TribufuHttp({
|
||||||
baseURL: TribufuApi.getBaseUrl(),
|
baseUrl: TribufuApi.getBaseUrl(),
|
||||||
headers: TribufuApi.defaultHeaders(),
|
headers: TribufuApi.defaultHeaders(),
|
||||||
|
logEnabled: TribufuApi.debugEnabled(),
|
||||||
});
|
});
|
||||||
|
|
||||||
http.interceptors.request.use((req) => {
|
|
||||||
if (TribufuApi.debugEnabled()) {
|
|
||||||
console.log(`(TribufuApi) ${req.method?.toUpperCase()} ${req.baseURL}${req.url}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const contentType = req.headers["Content-Type"];
|
|
||||||
if (req.data && (contentType === "application/json" || contentType === "application/x-www-form-urlencoded")) {
|
|
||||||
req.data = snakecaseKeys(req.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return req;
|
|
||||||
});
|
|
||||||
|
|
||||||
http.interceptors.response.use((res) => {
|
|
||||||
if (res.data) {
|
|
||||||
res.data = camelcaseKeys(res.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.http = http;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -235,90 +213,6 @@ export class TribufuApi {
|
|||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a resource from the Tribufu API.
|
|
||||||
* @returns T | null
|
|
||||||
*/
|
|
||||||
protected async get<T>(path: string, headers?: HeaderMap | null): Promise<T | null> {
|
|
||||||
try {
|
|
||||||
const requestHeaders = headers || this.getHeaders();
|
|
||||||
const response = await this.http.get(path, { headers: requestHeaders });
|
|
||||||
|
|
||||||
if (response.status !== 200) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.data as T;
|
|
||||||
} catch (error) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a resource to the Tribufu API.
|
|
||||||
* @param path
|
|
||||||
* @param body
|
|
||||||
* @param headers
|
|
||||||
* @returns T | null
|
|
||||||
*/
|
|
||||||
protected async post<S, T>(path: string, body: S, headers?: HeaderMap | null): Promise<T | null> {
|
|
||||||
try {
|
|
||||||
const requestHeaders = headers || this.getHeaders();
|
|
||||||
const response = await this.http.post(path, body, { headers: requestHeaders });
|
|
||||||
|
|
||||||
if (response.status !== 200) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.data as T;
|
|
||||||
} catch (error) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update a resource on the Tribufu API.
|
|
||||||
* @param path
|
|
||||||
* @param body
|
|
||||||
* @param headers
|
|
||||||
* @returns T | null
|
|
||||||
*/
|
|
||||||
protected async put<S, T>(path: string, body: S, headers?: HeaderMap | null): Promise<T | null> {
|
|
||||||
try {
|
|
||||||
const requestHeaders = headers || this.getHeaders();
|
|
||||||
const response = await this.http.put(path, body, { headers: requestHeaders });
|
|
||||||
|
|
||||||
if (response.status !== 200) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.data as T;
|
|
||||||
} catch (error) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a resource from the Tribufu API.
|
|
||||||
* @param path
|
|
||||||
* @param headers
|
|
||||||
* @returns T | null
|
|
||||||
*/
|
|
||||||
protected async delete<T>(path: string, headers?: HeaderMap | null): Promise<T | null> {
|
|
||||||
try {
|
|
||||||
const requestHeaders = headers || this.getHeaders();
|
|
||||||
const response = await this.http.delete(path, { headers: requestHeaders });
|
|
||||||
|
|
||||||
if (response.status !== 200) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.data as T;
|
|
||||||
} catch (error) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get games from the Tribufu API.
|
* Get games from the Tribufu API.
|
||||||
* @param page
|
* @param page
|
||||||
@ -326,7 +220,7 @@ export class TribufuApi {
|
|||||||
*/
|
*/
|
||||||
public async getGames(page: number = 1): Promise<any[]> {
|
public async getGames(page: number = 1): Promise<any[]> {
|
||||||
const headers = this.getHeaders();
|
const headers = this.getHeaders();
|
||||||
const responseBody = await this.get<any[]>(`/v1/packages?page=${page}`, headers);
|
const responseBody = await this.http.get<any[]>(`/v1/packages?page=${page}`, headers);
|
||||||
|
|
||||||
if (!responseBody) {
|
if (!responseBody) {
|
||||||
return [];
|
return [];
|
||||||
@ -342,7 +236,7 @@ export class TribufuApi {
|
|||||||
*/
|
*/
|
||||||
public async getGameyId(id: string): Promise<any | null> {
|
public async getGameyId(id: string): Promise<any | null> {
|
||||||
const headers = this.getHeaders();
|
const headers = this.getHeaders();
|
||||||
const responseBody = await this.get<any>(`/v1/packages/${id}`, headers);
|
const responseBody = await this.http.get<any>(`/v1/packages/${id}`, headers);
|
||||||
|
|
||||||
if (!responseBody) {
|
if (!responseBody) {
|
||||||
return null;
|
return null;
|
||||||
@ -358,7 +252,7 @@ export class TribufuApi {
|
|||||||
*/
|
*/
|
||||||
public async getServers(page: number = 1): Promise<any[]> {
|
public async getServers(page: number = 1): Promise<any[]> {
|
||||||
const headers = this.getHeaders();
|
const headers = this.getHeaders();
|
||||||
const responseBody = await this.get<any[]>(`/v1/servers?page=${page}`, headers);
|
const responseBody = await this.http.get<any[]>(`/v1/servers?page=${page}`, headers);
|
||||||
|
|
||||||
if (!responseBody) {
|
if (!responseBody) {
|
||||||
return [];
|
return [];
|
||||||
@ -387,7 +281,7 @@ export class TribufuApi {
|
|||||||
*/
|
*/
|
||||||
public async getServerById(id: string): Promise<any> {
|
public async getServerById(id: string): Promise<any> {
|
||||||
const headers = this.getHeaders()
|
const headers = this.getHeaders()
|
||||||
const responseBody = await this.get<any>(`/v1/servers/${id}`, headers);
|
const responseBody = await this.http.get<any>(`/v1/servers/${id}`, headers);
|
||||||
|
|
||||||
if (!responseBody) {
|
if (!responseBody) {
|
||||||
return null;
|
return null;
|
||||||
@ -403,7 +297,7 @@ export class TribufuApi {
|
|||||||
*/
|
*/
|
||||||
public async getServerByAddress(address: string): Promise<any> {
|
public async getServerByAddress(address: string): Promise<any> {
|
||||||
const headers = this.getHeaders();
|
const headers = this.getHeaders();
|
||||||
const responseBody = await this.get(`/v1/servers/address/${address}`, headers);
|
const responseBody = await this.http.get(`/v1/servers/address/${address}`, headers);
|
||||||
|
|
||||||
if (!responseBody) {
|
if (!responseBody) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -251,7 +251,7 @@ export class TribufuClient extends TribufuApi {
|
|||||||
|
|
||||||
const url = `/v1/oauth2/introspect`;
|
const url = `/v1/oauth2/introspect`;
|
||||||
const headers = this.getOAuthHeaders();
|
const headers = this.getOAuthHeaders();
|
||||||
const responseBody = await this.post<OAuth2IntrospectionRequest, OAuth2IntrospectionResponse>(url, requestBody, headers);
|
const responseBody = await this.http.post<OAuth2IntrospectionRequest, OAuth2IntrospectionResponse>(url, requestBody, headers);
|
||||||
|
|
||||||
if (!responseBody) {
|
if (!responseBody) {
|
||||||
return null;
|
return null;
|
||||||
@ -276,7 +276,7 @@ export class TribufuClient extends TribufuApi {
|
|||||||
|
|
||||||
const url = `/v1/oauth2/revoke`;
|
const url = `/v1/oauth2/revoke`;
|
||||||
const headers = this.getOAuthHeaders();
|
const headers = this.getOAuthHeaders();
|
||||||
const responseBody = await this.post<OAuth2IntrospectionRequest, OAuth2IntrospectionResponse>(url, requestBody, headers);
|
const responseBody = await this.http.post<OAuth2IntrospectionRequest, OAuth2IntrospectionResponse>(url, requestBody, headers);
|
||||||
|
|
||||||
if (!responseBody) {
|
if (!responseBody) {
|
||||||
return false;
|
return false;
|
||||||
@ -324,7 +324,7 @@ export class TribufuClient extends TribufuApi {
|
|||||||
const params = subjectKey && subjectValue ? `?${subjectKey}=${subjectValue}` : "";
|
const params = subjectKey && subjectValue ? `?${subjectKey}=${subjectValue}` : "";
|
||||||
const url = `/v1/oauth2/token${params}`;
|
const url = `/v1/oauth2/token${params}`;
|
||||||
const headers = this.getOAuthHeaders();
|
const headers = this.getOAuthHeaders();
|
||||||
const responseBody = await this.post<OAuth2TokenRequest, OAuth2TokenResponse>(url, requestBody, headers);
|
const responseBody = await this.http.post<OAuth2TokenRequest, OAuth2TokenResponse>(url, requestBody, headers);
|
||||||
|
|
||||||
if (!responseBody) {
|
if (!responseBody) {
|
||||||
return null;
|
return null;
|
||||||
@ -338,19 +338,17 @@ export class TribufuClient extends TribufuApi {
|
|||||||
* @returns User | null
|
* @returns User | null
|
||||||
*/
|
*/
|
||||||
public async getUserInfo(): Promise<User | null> {
|
public async getUserInfo(): Promise<User | null> {
|
||||||
if (!this.options.refreshToken) {
|
if (!this.options.accessToken) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const headers = this.getHeaders();
|
const headers = this.getHeaders();
|
||||||
const response = await this.http.get(`/v1/oauth2/userinfo`, { headers });
|
const responseBody = await this.http.get<User>(`/v1/oauth2/userinfo`, headers);
|
||||||
|
|
||||||
if (response.status !== 200) {
|
if (!responseBody) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = response.data as User;
|
return responseBody;
|
||||||
|
|
||||||
return user;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
17
src/http.ts
17
src/http.ts
@ -1,17 +0,0 @@
|
|||||||
// Copyright (c) Tribufu. All Rights Reserved.
|
|
||||||
|
|
||||||
export type HeaderMap = {
|
|
||||||
[key: string]: string
|
|
||||||
};
|
|
||||||
|
|
||||||
export type CookieMap = {
|
|
||||||
[key: string]: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface ErrorResponse {
|
|
||||||
error: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface MessageResponse {
|
|
||||||
message: string;
|
|
||||||
};
|
|
192
src/http/index.ts
Normal file
192
src/http/index.ts
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
// Copyright (c) Tribufu. All Rights Reserved.
|
||||||
|
|
||||||
|
import axios, { AxiosInstance } from "axios";
|
||||||
|
import camelcaseKeys from "camelcase-keys";
|
||||||
|
import snakecaseKeys from "snakecase-keys";
|
||||||
|
|
||||||
|
export type HeaderMap = {
|
||||||
|
[key: string]: string
|
||||||
|
};
|
||||||
|
|
||||||
|
export type CookieMap = {
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface ErrorResponse {
|
||||||
|
error: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface MessageResponse {
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface TribufuHttpOptions {
|
||||||
|
baseUrl?: string | null;
|
||||||
|
headers?: HeaderMap;
|
||||||
|
logEnabled?: boolean;
|
||||||
|
logTarget?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tribufu Http
|
||||||
|
*
|
||||||
|
* Helper class to make HTTP requests to the Tribufu API.
|
||||||
|
*/
|
||||||
|
export class TribufuHttp {
|
||||||
|
private readonly inner: AxiosInstance;
|
||||||
|
protected readonly options: TribufuHttpOptions;
|
||||||
|
|
||||||
|
constructor(options?: TribufuHttpOptions | null) {
|
||||||
|
const defaultOptions = TribufuHttp.defaultOptions();
|
||||||
|
|
||||||
|
this.options = {
|
||||||
|
baseUrl: options?.baseUrl || defaultOptions.baseUrl,
|
||||||
|
headers: options?.headers || defaultOptions.headers,
|
||||||
|
logEnabled: options?.logEnabled || defaultOptions.logEnabled,
|
||||||
|
logTarget: options?.logTarget || defaultOptions.logTarget,
|
||||||
|
};
|
||||||
|
|
||||||
|
const inner = axios.create({
|
||||||
|
baseURL: this.options?.baseUrl || undefined,
|
||||||
|
headers: this.options?.headers || undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
inner.interceptors.request.use((req) => {
|
||||||
|
if (this.options.logEnabled ?? false) {
|
||||||
|
console.log(`(${this.options.logTarget}) ${req.method?.toUpperCase()} ${req.baseURL}${req.url}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const contentType = req.headers["Content-Type"];
|
||||||
|
if (req.data && (contentType === "application/json" || contentType === "application/x-www-form-urlencoded")) {
|
||||||
|
req.data = snakecaseKeys(req.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return req;
|
||||||
|
});
|
||||||
|
|
||||||
|
inner.interceptors.response.use((res) => {
|
||||||
|
if (res.data) {
|
||||||
|
res.data = camelcaseKeys(res.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.inner = inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static defaultOptions(): TribufuHttpOptions {
|
||||||
|
return {
|
||||||
|
baseUrl: null,
|
||||||
|
headers: {},
|
||||||
|
logEnabled: false,
|
||||||
|
logTarget: "TribufuHttp",
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a resource from the Tribufu API.
|
||||||
|
* @returns T | null
|
||||||
|
*/
|
||||||
|
public async get<T>(path: string, headers?: HeaderMap | null): Promise<T | null> {
|
||||||
|
try {
|
||||||
|
const requestHeaders = headers || this.options.headers;
|
||||||
|
const response = await this.inner.get(path, { headers: requestHeaders });
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.data as T;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a resource to the Tribufu API.
|
||||||
|
* @param path
|
||||||
|
* @param body
|
||||||
|
* @param headers
|
||||||
|
* @returns T | null
|
||||||
|
*/
|
||||||
|
public async post<S, T>(path: string, body: S, headers?: HeaderMap | null): Promise<T | null> {
|
||||||
|
try {
|
||||||
|
const requestHeaders = headers || this.options.headers;
|
||||||
|
const response = await this.inner.post(path, body, { headers: requestHeaders });
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.data as T;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a resource on the Tribufu API.
|
||||||
|
* @param path
|
||||||
|
* @param body
|
||||||
|
* @param headers
|
||||||
|
* @returns T | null
|
||||||
|
*/
|
||||||
|
public async put<S, T>(path: string, body: S, headers?: HeaderMap | null): Promise<T | null> {
|
||||||
|
try {
|
||||||
|
const requestHeaders = headers || this.options.headers;
|
||||||
|
const response = await this.inner.put(path, body, { headers: requestHeaders });
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.data as T;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patch a resource on the Tribufu API.
|
||||||
|
* @param path
|
||||||
|
* @param body
|
||||||
|
* @param headers
|
||||||
|
* @returns T | null
|
||||||
|
*/
|
||||||
|
public async patch<S, T>(path: string, body: S, headers?: HeaderMap | null): Promise<T | null> {
|
||||||
|
try {
|
||||||
|
const requestHeaders = headers || this.options.headers;
|
||||||
|
const response = await this.inner.patch(path, body, { headers: requestHeaders });
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.data as T;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a resource from the Tribufu API.
|
||||||
|
* @param path
|
||||||
|
* @param headers
|
||||||
|
* @returns T | null
|
||||||
|
*/
|
||||||
|
public async delete<T>(path: string, headers?: HeaderMap | null): Promise<T | null> {
|
||||||
|
try {
|
||||||
|
const requestHeaders = headers || this.options.headers;
|
||||||
|
const response = await this.inner.delete(path, { headers: requestHeaders });
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.data as T;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
src/socket/index.ts
Normal file
11
src/socket/index.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) Tribufu. All Rights Reserved.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tribufu Socket
|
||||||
|
*
|
||||||
|
* Helper class to connect to the Tribufu Socket API.
|
||||||
|
*/
|
||||||
|
export class TribufuSocket {
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user