From a2fea020e0669a4cda3e324f47eba218d5b67d8e Mon Sep 17 00:00:00 2001 From: Ingerid Gjeitnes Hellen Date: Tue, 5 Sep 2023 14:26:48 +0200 Subject: [PATCH] chore: generate api with axios --- web/generate-api-typescript-client.sh | 2 +- web/src/api/generated/core/request.ts | 103 +++++++++++++------------- 2 files changed, 52 insertions(+), 53 deletions(-) diff --git a/web/generate-api-typescript-client.sh b/web/generate-api-typescript-client.sh index a8bfa2cf..0594cd9a 100755 --- a/web/generate-api-typescript-client.sh +++ b/web/generate-api-typescript-client.sh @@ -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" diff --git a/web/src/api/generated/core/request.ts b/web/src/api/generated/core/request.ts index b018a07c..1142d432 100644 --- a/web/src/api/generated/core/request.ts +++ b/web/src/api/generated/core/request.ts @@ -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'; @@ -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); @@ -136,22 +144,24 @@ export const resolve = async (options: ApiRequestOptions, resolver?: T | Reso return resolver; }; -export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions): Promise => { +export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions, formData?: FormData): Promise> => { 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); + .filter(([_, value]) => isDefined(value)) + .reduce((headers, [key, value]) => ({ + ...headers, + [key]: String(value), + }), {} as Record); if (isStringWithValue(token)) { headers['Authorization'] = `Bearer ${token}`; @@ -174,52 +184,53 @@ 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 ( config: OpenAPIConfig, options: ApiRequestOptions, url: string, body: any, formData: FormData | undefined, - headers: Headers, - onCancel: OnCancel -): Promise => { - const controller = new AbortController(); - - const request: RequestInit = { + headers: Record, + onCancel: OnCancel, + axiosClient: AxiosInstance +): Promise> => { + 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; + if (axiosError.response) { + return axiosError.response; + } + throw error; + } }; -export const getResponseHeader = (response: Response, responseHeader?: string): string | undefined => { +export const getResponseHeader = (response: AxiosResponse, responseHeader?: string): string | undefined => { if (responseHeader) { - const content = response.headers.get(responseHeader); + const content = response.headers[responseHeader]; if (isString(content)) { return content; } @@ -227,22 +238,9 @@ export const getResponseHeader = (response: Response, responseHeader?: string): return undefined; }; -export const getResponseBody = async (response: Response): Promise => { +export const getResponseBody = (response: AxiosResponse): 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; }; @@ -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 * @throws ApiError */ -export const request = (config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise => { +export const request = (config: OpenAPIConfig, options: ApiRequestOptions, axiosClient: AxiosInstance = axios): CancelablePromise => { 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(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,