Skip to content

Commit 02c4b15

Browse files
author
Максим Калин
committed
2 parents 7119306 + 17a504d commit 02c4b15

19 files changed

+128
-10
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Model } from './Model';
22

33
export interface OperationParameter extends Model {
4-
in: 'path' | 'query' | 'header' | 'formData' | 'body' | 'cookie';
4+
in: 'path' | 'query' | 'header' | 'formData' | 'body' | 'cookie' | 'axios';
55
prop: string;
66
mediaType: string | null;
77
}

src/openApi/v2/parser/getServices.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,27 @@ export const getServices = (openApi: OpenApi): Service[] => {
3131
const tags = op.tags?.length ? op.tags.filter(unique) : ['Default'];
3232
tags.forEach(tag => {
3333
const operation = getOperation(openApi, url, method, tag, op, pathParams);
34-
35-
// If we have already declared a service, then we should fetch that and
34+
operation.parameters.push({
35+
in: 'axios',
36+
prop: 'axiosConfig',
37+
export: 'generic',
38+
name: 'axiosConfig',
39+
type: 'AxiosRequestConfig',
40+
base: 'AxiosRequestConfig',
41+
template: null,
42+
link: null,
43+
description: 'AxiosConfig',
44+
isDefinition: false,
45+
isReadOnly: false,
46+
isRequired: false,
47+
isNullable: false,
48+
imports: [],
49+
enum: [],
50+
enums: [],
51+
properties: [],
52+
mediaType: null,
53+
});
54+
// If we have already de clared a service, then we should fetch that and
3655
// append the new method to it. Otherwise we should create a new service object.
3756
const service: Service = services.get(operation.service) || {
3857
name: operation.service,

src/openApi/v3/parser/getServices.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,26 @@ export const getServices = (openApi: OpenApi): Service[] => {
3131
const tags = op.tags?.length ? op.tags.filter(unique) : ['Default'];
3232
tags.forEach(tag => {
3333
const operation = getOperation(openApi, url, method, tag, op, pathParams);
34-
34+
operation.parameters.push({
35+
in: 'axios',
36+
prop: 'axiosConfig',
37+
export: 'generic',
38+
name: 'axiosConfig',
39+
type: 'AxiosRequestConfig',
40+
base: 'AxiosRequestConfig',
41+
template: null,
42+
link: null,
43+
description: 'AxiosConfig',
44+
isDefinition: false,
45+
isReadOnly: false,
46+
isRequired: false,
47+
isNullable: false,
48+
imports: [],
49+
enum: [],
50+
enums: [],
51+
properties: [],
52+
mediaType: null,
53+
});
3554
// If we have already declared a service, then we should fetch that and
3655
// append the new method to it. Otherwise we should create a new service object.
3756
const service: Service = services.get(operation.service) || {

src/templates/core/BaseHttpRequest.hbs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type { Observable } from 'rxjs';
77
import type { ApiRequestOptions } from './ApiRequestOptions';
88
import type { OpenAPIConfig } from './OpenAPI';
99
{{else}}
10+
import { AxiosInstance, AxiosRequestConfig } from 'axios';
1011
import type { ApiRequestOptions } from './ApiRequestOptions';
1112
import type { CancelablePromise } from './CancelablePromise';
1213
import type { OpenAPIConfig } from './OpenAPI';
@@ -26,6 +27,7 @@ export abstract class BaseHttpRequest {
2627
{{#equals @root.httpClient 'angular'}}
2728
public abstract request<T>(options: ApiRequestOptions): Observable<T>;
2829
{{else}}
29-
public abstract request<T>(options: ApiRequestOptions): CancelablePromise<T>;
30+
public axiosInstance: AxiosInstance;
31+
public abstract request<T>(options: ApiRequestOptions, axiosConfig?: AxiosRequestConfig): CancelablePromise<T>;
3032
{{/equals}}
3133
}

src/templates/core/axios/request.hbs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ import type { OpenAPIConfig } from './OpenAPI';
7070
* @returns CancelablePromise<T>
7171
* @throws ApiError
7272
*/
73-
export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions, axiosClient: AxiosInstance = axios): CancelablePromise<T> => {
73+
export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions, axiosClient: AxiosInstance = axios, axiosConfig?: AxiosRequestConfig,): CancelablePromise<T> => {
7474
return new CancelablePromise(async (resolve, reject, onCancel) => {
7575
try {
7676
const url = getUrl(config, options);
@@ -79,7 +79,7 @@ export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions, ax
7979
const headers = await getHeaders(config, options, formData);
8080

8181
if (!onCancel.isCancelled) {
82-
const response = await sendRequest<T>(config, options, url, body, formData, headers, onCancel, axiosClient);
82+
const response = await sendRequest<T>(config, options, url, body, formData, headers, onCancel, axiosClient, axiosConfig);
8383
const responseBody = getResponseBody(response);
8484
const responseHeader = getResponseHeader(response, options.responseHeader);
8585

src/templates/core/axios/sendRequest.hbs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ export const sendRequest = async <T>(
66
formData: FormData | undefined,
77
headers: Record<string, string>,
88
onCancel: OnCancel,
9-
axiosClient: AxiosInstance
9+
axiosClient: AxiosInstance,
10+
axiosConfig?: AxiosRequestConfig,
1011
): Promise<AxiosResponse<T>> => {
1112
const source = axios.CancelToken.source();
1213

@@ -17,6 +18,7 @@ export const sendRequest = async <T>(
1718
method: options.method,
1819
withCredentials: config.WITH_CREDENTIALS,
1920
cancelToken: source.token,
21+
...axiosConfig,
2022
};
2123

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

src/templates/exportService.hbs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{{>header}}
2-
2+
import { AxiosRequestConfig } from "axios";
33
{{#equals @root.httpClient 'angular'}}
44
{{#if @root.exportClient}}
55
import { Injectable } from '@angular/core';
@@ -145,7 +145,7 @@ export class {{{name}}}{{{@root.postfix}}} {
145145
{{/each}}
146146
},
147147
{{/if}}
148-
});
148+
}, axiosConfig);
149149
}
150150

151151
{{/each}}

src/templates/index.hbs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
{{#if @root.exportClient}}
44
export { {{{clientName}}} } from './{{{clientName}}}';
5+
export { {{{clientName}}}Client } from "./instance";
56

67
{{/if}}
78
{{#if @root.exportCore}}

src/templates/instance.hbs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import Axios, { AxiosRequestConfig } from 'axios';
2+
import axiosRetry from 'axios-retry';
3+
4+
import { BaseHttpRequest } from './core/BaseHttpRequest';
5+
import { OpenAPIConfig } from './core/OpenAPI';
6+
import { ApiRequestOptions } from './core/ApiRequestOptions';
7+
import { CancelablePromise } from './core/CancelablePromise';
8+
import { request as __request } from './core/request';
9+
10+
import { {{clientName}} } from './{{clientName}}';
11+
12+
type HttpRequestConstructor = new (config: OpenAPIConfig) => BaseHttpRequest;
13+
14+
export class AxiosHttpRequestWithRetry extends BaseHttpRequest {
15+
axiosInstance = Axios.create();
16+
17+
constructor(config: OpenAPIConfig) {
18+
super(config);
19+
axiosRetry(this.axiosInstance, {
20+
retryCondition: (error) => {
21+
if (!error.response) return false;
22+
23+
return error.response.status >= 400;
24+
},
25+
});
26+
}
27+
28+
public override request<T>(options: ApiRequestOptions, axiosConfig?: AxiosRequestConfig): CancelablePromise<T> {
29+
return __request(this.config, options, this.axiosInstance, axiosConfig);
30+
}
31+
}
32+
33+
export const {{clientName}}Client = (
34+
config?: Partial<OpenAPIConfig>,
35+
HttpRequest: HttpRequestConstructor = AxiosHttpRequestWithRetry
36+
) => new {{clientName}}(config, HttpRequest);

src/utils/registerHandlebarTemplates.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ import templateExportModel from '../templates/exportModel.hbs';
5656
import templateExportSchema from '../templates/exportSchema.hbs';
5757
import templateExportService from '../templates/exportService.hbs';
5858
import templateIndex from '../templates/index.hbs';
59+
import templateInstance from '../templates/instance.hbs';
5960
import partialBase from '../templates/partials/base.hbs';
6061
import partialExportComposition from '../templates/partials/exportComposition.hbs';
6162
import partialExportEnum from '../templates/partials/exportEnum.hbs';
@@ -88,6 +89,7 @@ import { registerHandlebarHelpers } from './registerHandlebarHelpers';
8889
export interface Templates {
8990
index: Handlebars.TemplateDelegate;
9091
client: Handlebars.TemplateDelegate;
92+
instance: Handlebars.TemplateDelegate;
9193
exports: {
9294
model: Handlebars.TemplateDelegate;
9395
schema: Handlebars.TemplateDelegate;
@@ -119,6 +121,7 @@ export const registerHandlebarTemplates = (root: {
119121
// Main templates (entry points for the files we write to disk)
120122
const templates: Templates = {
121123
index: Handlebars.template(templateIndex),
124+
instance: Handlebars.template(templateInstance),
122125
client: Handlebars.template(templateClient),
123126
exports: {
124127
model: Handlebars.template(templateExportModel),

0 commit comments

Comments
 (0)