Version 3 starter

This commit is contained in:
Jamie Curnow
2021-06-14 19:29:35 +10:00
parent 60fc57431a
commit 6205434140
642 changed files with 25817 additions and 32319 deletions

View File

@@ -0,0 +1,89 @@
import { camelizeKeys, decamelizeKeys } from "humps";
import AuthStore from "modules/AuthStore";
import * as queryString from "query-string";
interface BuildUrlArgs {
url: string;
params?: queryString.StringifiableRecord;
}
function buildUrl({ url, params }: BuildUrlArgs) {
const endpoint = url.replace(/^\/|\/$/g, "");
const apiParams = params ? `?${queryString.stringify(params)}` : "";
const apiUrl = `/api/${endpoint}${apiParams}`;
return apiUrl;
}
function buildAuthHeader(): Record<string, string> | undefined {
if (AuthStore.token) {
return { Authorization: `Bearer ${AuthStore.token.token}` };
}
return {};
}
function buildBody(data?: Record<string, any>) {
if (data) {
return JSON.stringify(decamelizeKeys(data));
}
}
async function processResponse(response: Response) {
const payload = await response.json();
if (!response.ok) {
throw new Error(payload.error.message);
}
return camelizeKeys(payload) as any;
}
interface GetArgs {
url: string;
params?: queryString.StringifiableRecord;
}
export async function get(
{ url, params }: GetArgs,
abortController?: AbortController,
) {
const apiUrl = buildUrl({ url, params });
const method = "GET";
const signal = abortController?.signal;
const headers = buildAuthHeader();
const response = await fetch(apiUrl, { method, headers, signal });
return processResponse(response);
}
interface PostArgs {
url: string;
data?: any;
}
export async function post(
{ url, data }: PostArgs,
abortController?: AbortController,
) {
const apiUrl = buildUrl({ url });
const method = "POST";
const headers = { ...buildAuthHeader(), "Content-Type": "application/json" };
const signal = abortController?.signal;
const body = buildBody(data);
const response = await fetch(apiUrl, { method, headers, body, signal });
return processResponse(response);
}
interface PutArgs {
url: string;
data?: any;
}
export async function put(
{ url, data }: PutArgs,
abortController?: AbortController,
) {
const apiUrl = buildUrl({ url });
const method = "PUT";
const headers = { ...buildAuthHeader(), "Content-Type": "application/json" };
const signal = abortController?.signal;
const body = buildBody(data);
const response = await fetch(apiUrl, { method, headers, body, signal });
return processResponse(response);
}

View File

@@ -0,0 +1,32 @@
import * as api from "./base";
import { UserResponse } from "./responseTypes";
interface AuthOptions {
type: string;
secret: string;
}
interface Options {
payload: {
name: string;
nickname: string;
email: string;
roles: string[];
isDisabled: boolean;
auth: AuthOptions;
};
}
export async function createUser(
{ payload }: Options,
abortController?: AbortController,
): Promise<UserResponse> {
const { result } = await api.post(
{
url: "/users",
data: payload,
},
abortController,
);
return result;
}

View File

@@ -0,0 +1,24 @@
import * as api from "./base";
import { TokenResponse } from "./responseTypes";
interface Options {
payload: {
type: string;
identity: string;
secret: string;
};
}
export async function getToken(
{ payload }: Options,
abortController?: AbortController,
): Promise<TokenResponse> {
const { result } = await api.post(
{
url: "/tokens",
data: payload,
},
abortController,
);
return result;
}

View File

@@ -0,0 +1,12 @@
import * as api from "./base";
import { UserResponse } from "./responseTypes";
export async function getUser(
id: number | string = "me",
): Promise<UserResponse> {
const userId = id ? id : "me";
const { result } = await api.get({
url: `/users/${userId}`,
});
return result;
}

View File

@@ -0,0 +1,6 @@
export * from "./createUser";
export * from "./getToken";
export * from "./getUser";
export * from "./refreshToken";
export * from "./requestHealth";
export * from "./responseTypes";

View File

@@ -0,0 +1,14 @@
import * as api from "./base";
import { TokenResponse } from "./responseTypes";
export async function refreshToken(
abortController?: AbortController,
): Promise<TokenResponse> {
const { result } = await api.get(
{
url: "/tokens",
},
abortController,
);
return result;
}

View File

@@ -0,0 +1,15 @@
import * as api from "./base";
import { HealthResponse } from "./responseTypes";
// Request function.
export async function requestHealth(
abortController?: AbortController,
): Promise<HealthResponse> {
const { result } = await api.get(
{
url: "",
},
abortController,
);
return result;
}

View File

@@ -0,0 +1,33 @@
export interface HealthResponse {
commit: string;
errorReporting: boolean;
healthy: boolean;
setup: boolean;
version: string;
}
export interface UserAuthResponse {
id: number;
userId: number;
type: string;
createdOn: number;
updatedOn: number;
}
export interface TokenResponse {
expires: number;
token: string;
}
export interface UserResponse {
id: number;
name: string;
nickname: string;
email: string;
createdOn: number;
updatedOn: number;
roles: string[];
gravatarUrl: string;
isDisabled: boolean;
auth?: UserAuthResponse;
}