Init
This commit is contained in:
commit
0029086b3f
148 changed files with 19047 additions and 0 deletions
3
shared/client-api/.eslintrc.js
Normal file
3
shared/client-api/.eslintrc.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
extends: ['../../.eslintrc.js'],
|
||||
};
|
39
shared/client-api/README.md
Normal file
39
shared/client-api/README.md
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Client API
|
||||
|
||||
A client side library intended to be used in multiple clients, such as admin, web and mobile. It handles authenticated and un-authenticated requests to the projects API.
|
||||
|
||||
## Type Naming
|
||||
|
||||
Consider naming after the group of API endpoints, such as Admin, for all admin API requests.
|
||||
|
||||
## Working With Baseblocks
|
||||
|
||||
New api endpoints may be manually added to this folder. A Baseblock may also add new API files during its installation.
|
||||
|
||||
## Using Client API in a Client
|
||||
|
||||
Add a new "include" to the client `tsconfig.json` (e.g. `packages/web/tsconfig.json`)
|
||||
|
||||
```
|
||||
"include": ["../shared/client-api"]
|
||||
```
|
||||
|
||||
Add a new dependency to the client `package.json` (e.g. `packages/web/package.json`)
|
||||
|
||||
```
|
||||
"@baseline/client-api": "1.0.0",
|
||||
```
|
||||
|
||||
Referencing the client api in code
|
||||
|
||||
```
|
||||
import { createAdmin } from '@baseline/client-api/admin';
|
||||
```
|
||||
|
||||
If you are having issues with your IDE showing this package as not existing attempt restarting your IDE TS Server and IDE ESLint Server.
|
||||
|
||||
## Note on Amplify
|
||||
|
||||
Since the package uses Amplify Auth for handling requests the same version must match all client versions or you will find that API requests will have authentication issues.
|
||||
|
||||
Confirm `aws-amplify` version in `package.json` is the same as the client `package.json`.
|
61
shared/client-api/admin.ts
Normal file
61
shared/client-api/admin.ts
Normal file
|
@ -0,0 +1,61 @@
|
|||
import { Admin } from '@baseline/types/admin';
|
||||
import { RequestHandler } from './request-handler';
|
||||
|
||||
export const getAllAdmins = async (
|
||||
requestHandler: RequestHandler,
|
||||
): Promise<Admin[]> => {
|
||||
const response = await requestHandler.request<Admin[]>({
|
||||
method: 'GET',
|
||||
url: `admin/list`,
|
||||
hasAuthentication: true,
|
||||
});
|
||||
if ('data' in response) {
|
||||
return response.data;
|
||||
}
|
||||
throw response;
|
||||
};
|
||||
|
||||
export const deleteAdmin = async (
|
||||
requestHandler: RequestHandler,
|
||||
data: { adminId: string },
|
||||
): Promise<boolean> => {
|
||||
const response = await requestHandler.request<boolean>({
|
||||
method: 'DELETE',
|
||||
url: `admin/${data.adminId}`,
|
||||
hasAuthentication: true,
|
||||
});
|
||||
if ('data' in response) {
|
||||
return response.data;
|
||||
}
|
||||
throw response;
|
||||
};
|
||||
|
||||
export const createAdmin = async (
|
||||
requestHandler: RequestHandler,
|
||||
data: { userEmail: string },
|
||||
): Promise<Admin> => {
|
||||
const response = await requestHandler.request<Admin>({
|
||||
method: 'POST',
|
||||
url: `admin`,
|
||||
hasAuthentication: true,
|
||||
data,
|
||||
});
|
||||
if ('data' in response) {
|
||||
return response.data;
|
||||
}
|
||||
throw response;
|
||||
};
|
||||
|
||||
export const checkAdmin = async (
|
||||
requestHandler: RequestHandler,
|
||||
): Promise<boolean> => {
|
||||
const response = await requestHandler.request<Admin>({
|
||||
method: 'GET',
|
||||
url: `admin`,
|
||||
hasAuthentication: true,
|
||||
});
|
||||
if ('data' in response) {
|
||||
return !!response.data.userSub;
|
||||
}
|
||||
return false;
|
||||
};
|
64
shared/client-api/chart.ts
Normal file
64
shared/client-api/chart.ts
Normal file
|
@ -0,0 +1,64 @@
|
|||
import { Chart } from '@baseline/types/chart';
|
||||
import { getRequestHandler } from './request-handler';
|
||||
|
||||
export const getChart = async (chartId: string): Promise<Chart> => {
|
||||
const response = await getRequestHandler().request<Chart>({
|
||||
method: 'GET',
|
||||
url: `chart/admin/${chartId}`,
|
||||
hasAuthentication: true,
|
||||
});
|
||||
if ('data' in response) {
|
||||
return response.data;
|
||||
}
|
||||
throw response;
|
||||
};
|
||||
|
||||
export const getAllCharts = async (): Promise<Chart[]> => {
|
||||
const response = await getRequestHandler().request<Chart[]>({
|
||||
method: 'GET',
|
||||
url: `chart/admin/list`,
|
||||
hasAuthentication: true,
|
||||
});
|
||||
if ('data' in response) {
|
||||
return response.data;
|
||||
}
|
||||
throw response;
|
||||
};
|
||||
|
||||
export const deleteChart = async (chartId: string): Promise<boolean> => {
|
||||
const response = await getRequestHandler().request<boolean>({
|
||||
method: 'DELETE',
|
||||
url: `chart/admin/${chartId}`,
|
||||
hasAuthentication: true,
|
||||
});
|
||||
if ('data' in response) {
|
||||
return response.data;
|
||||
}
|
||||
throw response;
|
||||
};
|
||||
|
||||
export const createChart = async (chart: Partial<Chart>): Promise<Chart> => {
|
||||
const response = await getRequestHandler().request<Chart>({
|
||||
method: 'POST',
|
||||
url: `chart/admin`,
|
||||
hasAuthentication: true,
|
||||
data: chart,
|
||||
});
|
||||
if ('data' in response) {
|
||||
return response.data;
|
||||
}
|
||||
throw response;
|
||||
};
|
||||
|
||||
export const updateChart = async (chart: Partial<Chart>): Promise<Chart> => {
|
||||
const response = await getRequestHandler().request<Chart>({
|
||||
method: 'PATCH',
|
||||
url: `chart/admin`,
|
||||
hasAuthentication: true,
|
||||
data: chart,
|
||||
});
|
||||
if ('data' in response) {
|
||||
return response.data;
|
||||
}
|
||||
throw response;
|
||||
};
|
13
shared/client-api/package.json
Normal file
13
shared/client-api/package.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "@baseline/client-api",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"lint": "npx eslint --config '.eslintrc.js' '**/*.{ts,tsx,js}'",
|
||||
"pretty": "npx prettier --write '*.{ts,tsx,js,json,css,scss,md,yml,yaml,html}'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@baseline/types": "workspace:1.0.0",
|
||||
"axios": "1.7.7"
|
||||
}
|
||||
}
|
86
shared/client-api/request-handler.ts
Normal file
86
shared/client-api/request-handler.ts
Normal file
|
@ -0,0 +1,86 @@
|
|||
import axios, {
|
||||
AxiosError,
|
||||
AxiosRequestConfig,
|
||||
AxiosRequestHeaders,
|
||||
AxiosResponse,
|
||||
Method,
|
||||
} from 'axios';
|
||||
|
||||
let requestHandler: RequestHandler;
|
||||
|
||||
export const getRequestHandler = (): RequestHandler => {
|
||||
return requestHandler;
|
||||
};
|
||||
|
||||
export const createRequestHandler = (
|
||||
authorizedConfig?: (
|
||||
config: AxiosRequestConfig,
|
||||
) => Promise<AxiosRequestConfig>,
|
||||
unauthorizedConfig?: (
|
||||
config: AxiosRequestConfig,
|
||||
) => Promise<AxiosRequestConfig>,
|
||||
): RequestHandler => {
|
||||
requestHandler = new RequestHandler(authorizedConfig, unauthorizedConfig);
|
||||
return requestHandler;
|
||||
};
|
||||
|
||||
const baseUrl = process.env.REACT_APP_API_URL || '';
|
||||
|
||||
export interface RequestHandlerParams {
|
||||
method: Method;
|
||||
url: string;
|
||||
hasAuthentication?: boolean;
|
||||
data?: unknown;
|
||||
headers?: AxiosRequestHeaders;
|
||||
}
|
||||
|
||||
export class RequestHandler {
|
||||
public authorizedConfig: (
|
||||
config: AxiosRequestConfig,
|
||||
) => Promise<AxiosRequestConfig>;
|
||||
|
||||
public unauthorizedConfig: (
|
||||
config: AxiosRequestConfig,
|
||||
) => Promise<AxiosRequestConfig>;
|
||||
|
||||
constructor(
|
||||
authorizedConfig?: (
|
||||
config: AxiosRequestConfig,
|
||||
) => Promise<AxiosRequestConfig>,
|
||||
unauthorizedConfig?: (
|
||||
config: AxiosRequestConfig,
|
||||
) => Promise<AxiosRequestConfig>,
|
||||
) {
|
||||
this.authorizedConfig = authorizedConfig;
|
||||
this.unauthorizedConfig = unauthorizedConfig;
|
||||
}
|
||||
|
||||
public request = async <T>(
|
||||
params: RequestHandlerParams,
|
||||
): Promise<AxiosResponse<T> | AxiosError> => {
|
||||
try {
|
||||
let config: AxiosRequestConfig = {
|
||||
method: params.method,
|
||||
url: `${baseUrl}${params.url}`,
|
||||
data: params.data,
|
||||
headers: params.headers,
|
||||
};
|
||||
if (params.hasAuthentication) {
|
||||
if (this.authorizedConfig) {
|
||||
config = await this.authorizedConfig(config);
|
||||
}
|
||||
return await axios(config);
|
||||
}
|
||||
if (this.unauthorizedConfig) {
|
||||
config = await this.unauthorizedConfig(config);
|
||||
}
|
||||
return await axios(config);
|
||||
} catch (error) {
|
||||
if (axios.isAxiosError(error)) {
|
||||
return error;
|
||||
}
|
||||
console.error('API Request Failed: ', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue