swagger-typescript-api 9.2.0 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/LICENSE +21 -21
- package/README.md +19 -13
- package/index.d.ts +56 -57
- package/index.js +48 -73
- package/package.json +21 -15
- package/src/config.js +9 -0
- package/src/index.js +54 -7
- package/src/prettierOptions.js +23 -0
- package/src/routeNames.js +3 -7
- package/src/routes.js +91 -79
- package/src/schema.js +66 -43
- package/src/swagger.js +27 -7
- package/src/typeFormatters.js +2 -2
- package/src/utils/id.js +9 -0
- package/templates/base/data-contracts.eta +2 -1
- package/templates/base/http-clients/axios-http-client.eta +38 -18
- package/templates/base/http-clients/fetch-http-client.eta +9 -7
- package/templates/default/api.eta +1 -1
- package/templates/modular/api.eta +1 -1
package/src/swagger.js
CHANGED
|
@@ -17,8 +17,8 @@ const parseSwaggerFile = (file) => {
|
|
|
17
17
|
}
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
const getSwaggerFile = (pathToSwagger, urlToSwagger, disableStrictSSL, disableProxy) =>
|
|
21
|
-
new Promise((resolve) => {
|
|
20
|
+
const getSwaggerFile = (pathToSwagger, urlToSwagger, disableStrictSSL, disableProxy, authorizationToken) =>
|
|
21
|
+
new Promise((resolve, reject) => {
|
|
22
22
|
if (pathIsExist(pathToSwagger)) {
|
|
23
23
|
logger.log(`try to get swagger by path "${pathToSwagger}"`);
|
|
24
24
|
resolve(getFileContent(pathToSwagger));
|
|
@@ -33,21 +33,40 @@ const getSwaggerFile = (pathToSwagger, urlToSwagger, disableStrictSSL, disablePr
|
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
//
|
|
36
|
+
if (authorizationToken) {
|
|
37
|
+
axiosOptions.headers = {
|
|
38
|
+
Authorization: authorizationToken,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//
|
|
36
42
|
if (disableProxy) axiosOptions.proxy = false;
|
|
37
43
|
//
|
|
38
44
|
axios
|
|
39
45
|
.get(urlToSwagger, axiosOptions)
|
|
40
46
|
.then((res) => resolve(res.data))
|
|
41
|
-
.catch((
|
|
47
|
+
.catch((error) => {
|
|
48
|
+
const message = `error while getting swagger by URL ${urlToSwagger}`;
|
|
49
|
+
|
|
50
|
+
logger.error(message, "response" in error ? error.response : error);
|
|
51
|
+
|
|
52
|
+
reject(message);
|
|
53
|
+
});
|
|
42
54
|
}
|
|
43
55
|
});
|
|
44
56
|
|
|
45
|
-
const getSwaggerObject = (
|
|
46
|
-
|
|
47
|
-
|
|
57
|
+
const getSwaggerObject = (
|
|
58
|
+
pathToSwagger,
|
|
59
|
+
urlToSwagger,
|
|
60
|
+
disableStrictSSL,
|
|
61
|
+
disableProxy,
|
|
62
|
+
authorizationToken,
|
|
63
|
+
converterOptions,
|
|
64
|
+
) =>
|
|
65
|
+
getSwaggerFile(pathToSwagger, urlToSwagger, disableStrictSSL, disableProxy, authorizationToken).then((file) =>
|
|
66
|
+
convertSwaggerObject(parseSwaggerFile(file), converterOptions),
|
|
48
67
|
);
|
|
49
68
|
|
|
50
|
-
const convertSwaggerObject = (swaggerSchema) => {
|
|
69
|
+
const convertSwaggerObject = (swaggerSchema, converterOptions) => {
|
|
51
70
|
return new Promise((resolve) => {
|
|
52
71
|
swaggerSchema.info = _.merge(
|
|
53
72
|
{
|
|
@@ -63,6 +82,7 @@ const convertSwaggerObject = (swaggerSchema) => {
|
|
|
63
82
|
converter.convertObj(
|
|
64
83
|
swaggerSchema,
|
|
65
84
|
{
|
|
85
|
+
...converterOptions,
|
|
66
86
|
warnOnly: true,
|
|
67
87
|
refSiblings: "preserve",
|
|
68
88
|
rbname: "requestBodyName",
|
package/src/typeFormatters.js
CHANGED
|
@@ -18,10 +18,10 @@ const formatters = {
|
|
|
18
18
|
const extraSpace = " ";
|
|
19
19
|
const result = `${extraSpace}${part.field};\n`;
|
|
20
20
|
|
|
21
|
-
const comments = _.compact([part.title, part.description]).reduce(
|
|
21
|
+
const comments = _.uniq(_.compact([part.title, part.description]).reduce(
|
|
22
22
|
(acc, comment) => [...acc, ...comment.split(/\n/g)],
|
|
23
23
|
[],
|
|
24
|
-
);
|
|
24
|
+
));
|
|
25
25
|
|
|
26
26
|
const commonText = comments.length
|
|
27
27
|
? [
|
package/src/utils/id.js
ADDED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<%
|
|
2
2
|
const { modelTypes, utils } = it;
|
|
3
3
|
const { formatDescription, require, _ } = utils;
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
|
|
6
6
|
const dataContractTemplates = {
|
|
7
7
|
enum: (contract) => {
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
return _.compact([
|
|
22
22
|
contract.description && formatDescription(contract.description),
|
|
23
|
+
contract.typeData.deprecated === true && '@deprecated',
|
|
23
24
|
!_.isUndefined(contract.typeData.format) && `@format ${contract.typeData.format}`,
|
|
24
25
|
!_.isUndefined(contract.typeData.minimum) && `@min ${contract.typeData.minimum}`,
|
|
25
26
|
!_.isUndefined(contract.typeData.maximum) && `@max ${contract.typeData.maximum}`,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const { apiConfig, generateResponses, config } = it;
|
|
3
3
|
%>
|
|
4
4
|
|
|
5
|
-
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, ResponseType } from "axios";
|
|
5
|
+
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, ResponseType, HeadersDefaults } from "axios";
|
|
6
6
|
|
|
7
7
|
export type QueryParamsType = Record<string | number, any>;
|
|
8
8
|
|
|
@@ -53,20 +53,44 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
53
53
|
this.securityData = data
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
56
|
+
protected mergeRequestParams(params1: AxiosRequestConfig, params2?: AxiosRequestConfig): AxiosRequestConfig {
|
|
57
|
+
const method = params1.method || (params2 && params2.method)
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
...this.instance.defaults,
|
|
61
|
+
...params1,
|
|
62
|
+
...(params2 || {}),
|
|
63
|
+
headers: {
|
|
64
|
+
...((method && this.instance.defaults.headers[method.toLowerCase() as keyof HeadersDefaults]) || {}),
|
|
65
|
+
...(params1.headers || {}),
|
|
66
|
+
...((params2 && params2.headers) || {}),
|
|
67
|
+
},
|
|
68
|
+
};
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
|
|
71
|
+
protected stringifyFormItem(formItem: unknown) {
|
|
72
|
+
if (typeof formItem === "object" && formItem !== null) {
|
|
73
|
+
return JSON.stringify(formItem);
|
|
74
|
+
} else {
|
|
75
|
+
return `${formItem}`;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
protected createFormData(input: Record<string, unknown>): FormData {
|
|
80
|
+
return Object.keys(input || {}).reduce((formData, key) => {
|
|
81
|
+
const property = input[key];
|
|
82
|
+
const propertyContent: Iterable<any> = (property instanceof Array) ? property : [property]
|
|
83
|
+
|
|
84
|
+
for (const formItem of propertyContent) {
|
|
85
|
+
const isFileType = formItem instanceof Blob || formItem instanceof File;
|
|
86
|
+
formData.append(
|
|
87
|
+
key,
|
|
88
|
+
isFileType ? formItem : this.stringifyFormItem(formItem)
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return formData;
|
|
93
|
+
}, new FormData());
|
|
70
94
|
return Object.keys(input || {}).reduce((formData, key) => {
|
|
71
95
|
const property = input[key];
|
|
72
96
|
formData.append(
|
|
@@ -96,13 +120,9 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
96
120
|
<% } %>
|
|
97
121
|
const secureParams = ((typeof secure === 'boolean' ? secure : this.secure) && this.securityWorker && (await this.securityWorker(this.securityData))) || {};
|
|
98
122
|
const requestParams = this.mergeRequestParams(params, secureParams);
|
|
99
|
-
const responseFormat = (format
|
|
123
|
+
const responseFormat = (format || this.format) || undefined;
|
|
100
124
|
|
|
101
125
|
if (type === ContentType.FormData && body && body !== null && typeof body === "object") {
|
|
102
|
-
requestParams.headers.common = { Accept: "*/*" };
|
|
103
|
-
requestParams.headers.post = {};
|
|
104
|
-
requestParams.headers.put = {};
|
|
105
|
-
|
|
106
126
|
body = this.createFormData(body as Record<string, unknown>);
|
|
107
127
|
}
|
|
108
128
|
|
|
@@ -68,17 +68,17 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
68
68
|
public setSecurityData = (data: SecurityDataType | null) => {
|
|
69
69
|
this.securityData = data;
|
|
70
70
|
}
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
|
|
72
|
+
protected encodeQueryParam(key: string, value: any) {
|
|
73
73
|
const encodedKey = encodeURIComponent(key);
|
|
74
74
|
return `${encodedKey}=${encodeURIComponent(typeof value === "number" ? value : `${value}`)}`;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
protected addQueryParam(query: QueryParamsType, key: string) {
|
|
78
78
|
return this.encodeQueryParam(key, query[key]);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
protected addArrayQueryParam(query: QueryParamsType, key: string) {
|
|
82
82
|
const value = query[key];
|
|
83
83
|
return value.map((v: any) => this.encodeQueryParam(key, v)).join("&");
|
|
84
84
|
}
|
|
@@ -118,7 +118,7 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
118
118
|
[ContentType.UrlEncoded]: (input: any) => this.toQueryString(input),
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
protected mergeRequestParams(params1: RequestParams, params2?: RequestParams): RequestParams {
|
|
122
122
|
return {
|
|
123
123
|
...this.baseApiParams,
|
|
124
124
|
...params1,
|
|
@@ -131,7 +131,7 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
131
131
|
};
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
protected createAbortSignal = (cancelToken: CancelToken): AbortSignal | undefined => {
|
|
135
135
|
if (this.abortControllers.has(cancelToken)) {
|
|
136
136
|
const abortController = this.abortControllers.get(cancelToken);
|
|
137
137
|
if (abortController) {
|
|
@@ -183,7 +183,7 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
183
183
|
...(type && type !== ContentType.FormData ? { "Content-Type": type } : {}),
|
|
184
184
|
...(requestParams.headers || {}),
|
|
185
185
|
},
|
|
186
|
-
signal: cancelToken ? this.createAbortSignal(cancelToken) :
|
|
186
|
+
signal: cancelToken ? this.createAbortSignal(cancelToken) : requestParams.signal,
|
|
187
187
|
body: typeof body === "undefined" || body === null ? null : payloadFormatter(body),
|
|
188
188
|
}
|
|
189
189
|
).then(async (response) => {
|
|
@@ -209,7 +209,9 @@ export class HttpClient<SecurityDataType = unknown> {
|
|
|
209
209
|
this.abortControllers.delete(cancelToken);
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
+
<% if (!config.disableThrowOnError) { %>
|
|
212
213
|
if (!response.ok) throw data;
|
|
214
|
+
<% } %>
|
|
213
215
|
<% if (config.unwrapResponseData) { %>
|
|
214
216
|
return data.data;
|
|
215
217
|
<% } else { %>
|
|
@@ -36,7 +36,7 @@ const descriptionLines = _.compact([
|
|
|
36
36
|
<% }) %>
|
|
37
37
|
*/
|
|
38
38
|
<% } %>
|
|
39
|
-
export class
|
|
39
|
+
export class <%~ config.apiClassName %><SecurityDataType extends unknown><% if (!config.singleHttpClient) { %> extends HttpClient<SecurityDataType> <% } %> {
|
|
40
40
|
|
|
41
41
|
<% if(config.singleHttpClient) { %>
|
|
42
42
|
http: HttpClient<SecurityDataType>;
|
|
@@ -8,7 +8,7 @@ const dataContracts = _.map(modelTypes, "name");
|
|
|
8
8
|
|
|
9
9
|
<% if (config.httpClientType === config.constants.HTTP_CLIENT.AXIOS) { %> import { AxiosRequestConfig, AxiosResponse } from "axios"; <% } %>
|
|
10
10
|
|
|
11
|
-
import { HttpClient, RequestParams, ContentType } from "./<%~ config.fileNames.httpClient %>";
|
|
11
|
+
import { HttpClient, RequestParams, ContentType, HttpResponse } from "./<%~ config.fileNames.httpClient %>";
|
|
12
12
|
<% if (dataContracts.length) { %>
|
|
13
13
|
import { <%~ dataContracts.join(", ") %> } from "./<%~ config.fileNames.dataContracts %>"
|
|
14
14
|
<% } %>
|