Skip to content

Commit af151c6

Browse files
gerganAndreas Behrend
authored andcommitted
change the request generation for axios
1 parent 94254b5 commit af151c6

17 files changed

+304
-47
lines changed

package-lock.json

Lines changed: 37 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "typescript-openapi-codegen",
3-
"version": "0.24.0",
3+
"version": "0.2.0",
44
"description": "Library that generates Typescript clients based on the OpenAPI specification.",
55
"author": "Ferdi Koomen",
66
"homepage": "https://github.com/essquare/typescript-openapi-codegen",
@@ -95,7 +95,8 @@
9595
"@typescript-eslint/eslint-plugin": "5.36.2",
9696
"@typescript-eslint/parser": "5.37.0",
9797
"abort-controller": "3.0.0",
98-
"axios": "0.27.2",
98+
"axios": "^1.1.3",
99+
"bson": "^4.7.0",
99100
"codecov": "3.8.3",
100101
"cross-spawn": "7.0.3",
101102
"eslint": "8.23.1",

src/templates/core/angular/request.hbs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ import type { ApiRequestOptions } from './ApiRequestOptions';
1111
import type { ApiResult } from './ApiResult';
1212
import type { OpenAPIConfig } from './OpenAPI';
1313

14+
{{>functions/isBrowserEnv}}
15+
16+
17+
{{>functions/typeOfTest}}
18+
19+
20+
{{>functions/isFunction}}
21+
22+
1423
{{>functions/isDefined}}
1524

1625

src/templates/core/axios/getHeaders.hbs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions, formData?: FormData): Promise<Record<string, string>> => {
1+
const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions, formData?: any): Promise<Record<string, string>> => {
22
const token = await resolve(options, config.TOKEN);
33
const username = await resolve(options, config.USERNAME);
44
const password = await resolve(options, config.PASSWORD);
55
const additionalHeaders = await resolve(options, config.HEADERS);
6-
const formHeaders = typeof formData?.getHeaders === 'function' && formData?.getHeaders() || {}
6+
const formHeaders =
7+
(isFormData(formData) && typeof formData?.getHeaders === 'function' && formData?.getHeaders()) ||
8+
(isBlob(formData) && {'Content-Type': formData.type}) ||
9+
{};
710

811
const headers = Object.entries({
912
Accept: 'application/json',

src/templates/core/axios/request.hbs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{{>header}}
22

33
import axios from 'axios';
4-
import type { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios';
5-
import FormData from 'form-data';
4+
import type { AxiosError, AxiosRequestConfig, AxiosResponse, AxiosResponseTransformer } from 'axios';
5+
import { ObjectId } from 'bson';
66

77
import { ApiError } from './ApiError';
88
import type { ApiRequestOptions } from './ApiRequestOptions';
@@ -11,6 +11,18 @@ import { CancelablePromise } from './CancelablePromise';
1111
import type { OnCancel } from './CancelablePromise';
1212
import type { OpenAPIConfig } from './OpenAPI';
1313

14+
{{>functions/isBrowserEnv}}
15+
16+
17+
{{>functions/prepareFormData}}
18+
19+
20+
{{>functions/typeOfTest}}
21+
22+
23+
{{>functions/isFunction}}
24+
25+
1426
{{>functions/isDefined}}
1527

1628

@@ -73,7 +85,7 @@ export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions): C
7385
return new CancelablePromise(async (resolve, reject, onCancel) => {
7486
try {
7587
const url = getUrl(config, options);
76-
const formData = getFormData(options);
88+
const formData = prepareFormData(getFormData(options));
7789
const body = getRequestBody(options);
7890
const headers = await getHeaders(config, options, formData);
7991

src/templates/core/axios/sendRequest.hbs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,56 @@ const sendRequest = async <T>(
33
options: ApiRequestOptions,
44
url: string,
55
body: any,
6-
formData: FormData | undefined,
6+
formData: any,
77
headers: Record<string, string>,
88
onCancel: OnCancel
99
): Promise<AxiosResponse<T>> => {
1010
const source = axios.CancelToken.source();
11+
let realBody;
12+
if (body) {
13+
realBody = body;
14+
} else if (isFormData(formData)) {
15+
realBody = formData;
16+
}
17+
if (isBlob(formData)) {
18+
realBody = await formData.arrayBuffer();
19+
}
20+
21+
const transformers: AxiosResponseTransformer[] = [];
22+
23+
transformers.push(function binaryData(data, headers) {
24+
const contentType = (headers.getContentType() as string) || '';
25+
const hasJSONContentType = contentType.indexOf('application/json') > -1;
26+
const hasTextContentType = contentType.indexOf('text/plain') > -1;
27+
if (!hasJSONContentType && !hasTextContentType) {
28+
return new Blob([data]);
29+
}
30+
const textDecoder = new TextDecoder('utf-8');
31+
const textData = textDecoder.decode(data);
32+
if (this !== undefined) {
33+
if (hasJSONContentType) {
34+
this.responseType = "json"
35+
} else if (hasTextContentType && this !== undefined) {
36+
this.responseType = "text"
37+
}
38+
}
39+
return textData;
40+
});
41+
if (axios.defaults.transformResponse instanceof Array<AxiosResponseTransformer>) {
42+
transformers.push(...axios.defaults.transformResponse);
43+
} else if (axios.defaults.transformResponse !== undefined) {
44+
transformers.push(axios.defaults.transformResponse);
45+
}
1146

1247
const requestConfig: AxiosRequestConfig = {
1348
url,
1449
headers,
15-
data: body ?? formData,
50+
data: realBody,
1651
method: options.method,
1752
withCredentials: config.WITH_CREDENTIALS,
1853
cancelToken: source.token,
54+
transformResponse: transformers,
55+
responseType: 'arraybuffer',
1956
};
2057

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

src/templates/core/fetch/request.hbs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ import { CancelablePromise } from './CancelablePromise';
77
import type { OnCancel } from './CancelablePromise';
88
import type { OpenAPIConfig } from './OpenAPI';
99

10+
{{>functions/isBrowserEnv}}
11+
12+
13+
{{>functions/typeOfTest}}
14+
15+
16+
{{>functions/isFunction}}
17+
18+
1019
{{>functions/isDefined}}
1120

1221

src/templates/core/functions/getFormData.hbs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
1-
const getFormData = (options: ApiRequestOptions): FormData | undefined => {
1+
const getFormData = (options: ApiRequestOptions) => {
22
if (options.formData) {
3-
const formData = new FormData();
4-
5-
const process = (key: string, value: any) => {
6-
if (isString(value) || isBlob(value)) {
7-
formData.append(key, value);
8-
} else {
9-
formData.append(key, JSON.stringify(value));
10-
}
11-
};
3+
let formData: any;
4+
if (isStandardBrowserEnv) {
5+
formData = new FormData();
6+
} else {
7+
if (typeof FormData !== undefined) {
8+
formData = new FormData();
9+
} else {
10+
throw new Error('Please use with nodejs version >= 18!');
11+
}
12+
}
13+
14+
const process = (key: string, value: any) => {
15+
if (isString(value)) {
16+
formData.append(key, value);
17+
} else if (isBlob(value)) {
18+
formData.append(key, value, value.type);
19+
} else {
20+
formData.append(key, JSON.stringify(value));
21+
}
22+
};
1223

1324
Object.entries(options.formData)
1425
.filter(([_, value]) => isDefined(value))
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const isStandardBrowserEnv = (() => {
2+
let product;
3+
if (
4+
typeof navigator !== 'undefined' &&
5+
((product = navigator.product) === 'ReactNative' ||
6+
product === 'NativeScript' ||
7+
product === 'NS')
8+
) {
9+
return false;
10+
}
11+
12+
return typeof window !== 'undefined' && typeof document !== 'undefined';
13+
})();
Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1-
const isFormData = (value: any): value is FormData => {
2-
return value instanceof FormData;
3-
};
1+
const isFormData = (thing: any) => {
2+
const pattern = '[object FormData]';
3+
return (
4+
thing &&
5+
((typeof FormData === 'function' && thing instanceof FormData) ||
6+
toString.call(thing) === pattern ||
7+
(isFunction(thing.toString) && thing.toString() === pattern))
8+
);
9+
};

0 commit comments

Comments
 (0)