Skip to content

Commit

Permalink
chore: generate api with axios
Browse files Browse the repository at this point in the history
  • Loading branch information
ingeridhellen committed Sep 5, 2023
1 parent 6c45021 commit a2fea02
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 53 deletions.
2 changes: 1 addition & 1 deletion web/generate-api-typescript-client.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash

# This requires the API to be running on localhost port 5000
yarn openapi -i http://localhost:5000/openapi.json -o "$PWD/src/api/generated"
yarn openapi -i http://localhost:5000/openapi.json -o "$PWD/src/api/generated" -c "axios"

103 changes: 51 additions & 52 deletions web/src/api/generated/core/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import axios from 'axios';
import type { AxiosError, AxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios';
import FormData from 'form-data';

import { ApiError } from './ApiError';
import type { ApiRequestOptions } from './ApiRequestOptions';
import type { ApiResult } from './ApiResult';
Expand Down Expand Up @@ -38,6 +42,10 @@ export const isFormData = (value: any): value is FormData => {
return value instanceof FormData;
};

export const isSuccess = (status: number): boolean => {
return status >= 200 && status < 300;
};

export const base64 = (str: string): string => {
try {
return btoa(str);
Expand Down Expand Up @@ -136,22 +144,24 @@ export const resolve = async <T>(options: ApiRequestOptions, resolver?: T | Reso
return resolver;
};

export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions): Promise<Headers> => {
export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions, formData?: FormData): Promise<Record<string, string>> => {
const token = await resolve(options, config.TOKEN);
const username = await resolve(options, config.USERNAME);
const password = await resolve(options, config.PASSWORD);
const additionalHeaders = await resolve(options, config.HEADERS);
const formHeaders = typeof formData?.getHeaders === 'function' && formData?.getHeaders() || {}

const headers = Object.entries({
Accept: 'application/json',
...additionalHeaders,
...options.headers,
...formHeaders,
})
.filter(([_, value]) => isDefined(value))
.reduce((headers, [key, value]) => ({
...headers,
[key]: String(value),
}), {} as Record<string, string>);
.filter(([_, value]) => isDefined(value))
.reduce((headers, [key, value]) => ({
...headers,
[key]: String(value),
}), {} as Record<string, string>);

if (isStringWithValue(token)) {
headers['Authorization'] = `Bearer ${token}`;
Expand All @@ -174,75 +184,63 @@ export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptio
}
}

return new Headers(headers);
return headers;
};

export const getRequestBody = (options: ApiRequestOptions): any => {
if (options.body !== undefined) {
if (options.mediaType?.includes('/json')) {
return JSON.stringify(options.body)
} else if (isString(options.body) || isBlob(options.body) || isFormData(options.body)) {
return options.body;
} else {
return JSON.stringify(options.body);
}
if (options.body) {
return options.body;
}
return undefined;
};

export const sendRequest = async (
export const sendRequest = async <T>(
config: OpenAPIConfig,
options: ApiRequestOptions,
url: string,
body: any,
formData: FormData | undefined,
headers: Headers,
onCancel: OnCancel
): Promise<Response> => {
const controller = new AbortController();

const request: RequestInit = {
headers: Record<string, string>,
onCancel: OnCancel,
axiosClient: AxiosInstance
): Promise<AxiosResponse<T>> => {
const source = axios.CancelToken.source();

const requestConfig: AxiosRequestConfig = {
url,
headers,
body: body ?? formData,
data: body ?? formData,
method: options.method,
signal: controller.signal,
withCredentials: config.WITH_CREDENTIALS,
cancelToken: source.token,
};

if (config.WITH_CREDENTIALS) {
request.credentials = config.CREDENTIALS;
}

onCancel(() => controller.abort());
onCancel(() => source.cancel('The user aborted a request.'));

return await fetch(url, request);
try {
return await axiosClient.request(requestConfig);
} catch (error) {
const axiosError = error as AxiosError<T>;
if (axiosError.response) {
return axiosError.response;
}
throw error;
}
};

export const getResponseHeader = (response: Response, responseHeader?: string): string | undefined => {
export const getResponseHeader = (response: AxiosResponse<any>, responseHeader?: string): string | undefined => {
if (responseHeader) {
const content = response.headers.get(responseHeader);
const content = response.headers[responseHeader];
if (isString(content)) {
return content;
}
}
return undefined;
};

export const getResponseBody = async (response: Response): Promise<any> => {
export const getResponseBody = (response: AxiosResponse<any>): any => {
if (response.status !== 204) {
try {
const contentType = response.headers.get('Content-Type');
if (contentType) {
const jsonTypes = ['application/json', 'application/problem+json']
const isJSON = jsonTypes.some(type => contentType.toLowerCase().startsWith(type));
if (isJSON) {
return await response.json();
} else {
return await response.text();
}
}
} catch (error) {
console.error(error);
}
return response.data;
}
return undefined;
};
Expand Down Expand Up @@ -285,25 +283,26 @@ export const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult):
* Request method
* @param config The OpenAPI configuration object
* @param options The request options from the service
* @param axiosClient The axios client instance to use
* @returns CancelablePromise<T>
* @throws ApiError
*/
export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise<T> => {
export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions, axiosClient: AxiosInstance = axios): CancelablePromise<T> => {
return new CancelablePromise(async (resolve, reject, onCancel) => {
try {
const url = getUrl(config, options);
const formData = getFormData(options);
const body = getRequestBody(options);
const headers = await getHeaders(config, options);
const headers = await getHeaders(config, options, formData);

if (!onCancel.isCancelled) {
const response = await sendRequest(config, options, url, body, formData, headers, onCancel);
const responseBody = await getResponseBody(response);
const response = await sendRequest<T>(config, options, url, body, formData, headers, onCancel, axiosClient);
const responseBody = getResponseBody(response);
const responseHeader = getResponseHeader(response, options.responseHeader);

const result: ApiResult = {
url,
ok: response.ok,
ok: isSuccess(response.status),
status: response.status,
statusText: response.statusText,
body: responseHeader ?? responseBody,
Expand Down

0 comments on commit a2fea02

Please sign in to comment.