@toktokhan-dev/cli-plugin-gen-api-react-query 0.0.1
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/dist/index.d.ts +62 -0
- package/dist/index.js +196 -0
- package/package.json +40 -0
- package/templates/custom-axios/api.eta +176 -0
- package/templates/custom-axios/data-contracts.eta +76 -0
- package/templates/custom-axios/http-client.eta +144 -0
- package/templates/custom-axios/procedure-call.eta +133 -0
- package/templates/custom-fetch/api.eta +164 -0
- package/templates/custom-fetch/data-contracts.eta +76 -0
- package/templates/custom-fetch/http-client.eta +224 -0
- package/templates/custom-fetch/procedure-call.eta +151 -0
- package/templates/default/README.md +17 -0
- package/templates/default/base/README.md +8 -0
- package/templates/default/base/data-contract-jsdoc.ejs +37 -0
- package/templates/default/base/data-contracts.ejs +28 -0
- package/templates/default/base/enum-data-contract.ejs +12 -0
- package/templates/default/base/http-client.ejs +3 -0
- package/templates/default/base/http-clients/axios-http-client.ejs +138 -0
- package/templates/default/base/http-clients/fetch-http-client.ejs +224 -0
- package/templates/default/base/interface-data-contract.ejs +10 -0
- package/templates/default/base/object-field-jsdoc.ejs +28 -0
- package/templates/default/base/route-docs.ejs +30 -0
- package/templates/default/base/route-name.ejs +43 -0
- package/templates/default/base/route-type.ejs +22 -0
- package/templates/default/base/type-data-contract.ejs +15 -0
- package/templates/default/default/README.md +7 -0
- package/templates/default/default/api.ejs +65 -0
- package/templates/default/default/procedure-call.ejs +100 -0
- package/templates/default/default/route-types.ejs +28 -0
- package/templates/default/modular/README.md +7 -0
- package/templates/default/modular/api.ejs +28 -0
- package/templates/default/modular/procedure-call.ejs +100 -0
- package/templates/default/modular/route-types.ejs +18 -0
- package/templates/my/param-serializer-by.eta +41 -0
- package/templates/my/react-query-hook.eta +171 -0
- package/templates/my/react-query-key.eta +46 -0
- package/templates/my/react-query-type.eta +61 -0
- package/templates/my/util-types.eta +32 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<%
|
|
2
|
+
const { config, route, utils } = it;
|
|
3
|
+
const { _, formatDescription, fmtToJSDocLine, pascalCase, require } = utils;
|
|
4
|
+
const { raw, request, routeName } = route;
|
|
5
|
+
|
|
6
|
+
const jsDocDescription = raw.description ?
|
|
7
|
+
` * @description ${formatDescription(raw.description, true)}` :
|
|
8
|
+
fmtToJSDocLine('No description', { eol: false });
|
|
9
|
+
const jsDocLines = _.compact([
|
|
10
|
+
_.size(raw.tags) && ` * @tags ${raw.tags.join(", ")}`,
|
|
11
|
+
` * @name ${pascalCase(routeName.usage)}`,
|
|
12
|
+
raw.summary && ` * @summary ${raw.summary}`,
|
|
13
|
+
` * @request ${_.upperCase(request.method)}:${raw.route}`,
|
|
14
|
+
raw.deprecated && ` * @deprecated`,
|
|
15
|
+
routeName.duplicate && ` * @originalName ${routeName.original}`,
|
|
16
|
+
routeName.duplicate && ` * @duplicate`,
|
|
17
|
+
request.security && ` * @secure`,
|
|
18
|
+
...(config.generateResponses && raw.responsesTypes.length
|
|
19
|
+
? raw.responsesTypes.map(
|
|
20
|
+
({ type, status, description, isSuccess }) =>
|
|
21
|
+
` * @response \`${status}\` \`${_.replace(_.replace(type, /\/\*/g, "\\*"), /\*\//g, "*\\")}\` ${description}`,
|
|
22
|
+
)
|
|
23
|
+
: []),
|
|
24
|
+
]).map(str => str.trimEnd()).join("\n");
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
description: jsDocDescription,
|
|
28
|
+
lines: jsDocLines,
|
|
29
|
+
}
|
|
30
|
+
%>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<%
|
|
2
|
+
const { routeInfo, utils } = it;
|
|
3
|
+
const {
|
|
4
|
+
operationId,
|
|
5
|
+
method,
|
|
6
|
+
route,
|
|
7
|
+
moduleName,
|
|
8
|
+
responsesTypes,
|
|
9
|
+
description,
|
|
10
|
+
tags,
|
|
11
|
+
summary,
|
|
12
|
+
pathArgs,
|
|
13
|
+
} = routeInfo;
|
|
14
|
+
const { _, fmtToJSDocLine, require } = utils;
|
|
15
|
+
|
|
16
|
+
const methodAliases = {
|
|
17
|
+
get: (pathName, hasPathInserts) =>
|
|
18
|
+
_.camelCase(`${pathName}_${hasPathInserts ? "detail" : "list"}`),
|
|
19
|
+
post: (pathName, hasPathInserts) => _.camelCase(`${pathName}_create`),
|
|
20
|
+
put: (pathName, hasPathInserts) => _.camelCase(`${pathName}_update`),
|
|
21
|
+
patch: (pathName, hasPathInserts) => _.camelCase(`${pathName}_partial_update`),
|
|
22
|
+
delete: (pathName, hasPathInserts) => _.camelCase(`${pathName}_delete`),
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const createCustomOperationId = (method, route, moduleName) => {
|
|
26
|
+
const hasPathInserts = /\{(\w){1,}\}/g.test(route);
|
|
27
|
+
const splitedRouteBySlash = _.compact(_.replace(route, /\{(\w){1,}\}/g, "").split("/"));
|
|
28
|
+
const routeParts = (splitedRouteBySlash.length > 1
|
|
29
|
+
? splitedRouteBySlash.splice(1)
|
|
30
|
+
: splitedRouteBySlash
|
|
31
|
+
).join("_");
|
|
32
|
+
return routeParts.length > 3 && methodAliases[method]
|
|
33
|
+
? methodAliases[method](routeParts, hasPathInserts)
|
|
34
|
+
: _.camelCase(_.lowerCase(method) + "_" + [moduleName].join("_")) || "index";
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
if (operationId)
|
|
38
|
+
return _.camelCase(operationId);
|
|
39
|
+
if (route === "/")
|
|
40
|
+
return _.camelCase(`${_.lowerCase(method)}Root`);
|
|
41
|
+
|
|
42
|
+
return createCustomOperationId(method, route, moduleName);
|
|
43
|
+
%>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<%
|
|
2
|
+
const { route, utils, config } = it;
|
|
3
|
+
const { _, pascalCase, require } = utils;
|
|
4
|
+
const { query, payload, pathParams, headers } = route.request;
|
|
5
|
+
|
|
6
|
+
const routeDocs = includeFile("@base/route-docs", { config, route, utils });
|
|
7
|
+
const routeNamespace = pascalCase(route.routeName.usage);
|
|
8
|
+
|
|
9
|
+
%>
|
|
10
|
+
/**
|
|
11
|
+
<%~ routeDocs.description %>
|
|
12
|
+
|
|
13
|
+
<%~ routeDocs.lines %>
|
|
14
|
+
|
|
15
|
+
*/
|
|
16
|
+
export namespace <%~ routeNamespace %> {
|
|
17
|
+
export type RequestParams = <%~ (pathParams && pathParams.type) || '{}' %>;
|
|
18
|
+
export type RequestQuery = <%~ (query && query.type) || '{}' %>;
|
|
19
|
+
export type RequestBody = <%~ (payload && payload.type) || 'never' %>;
|
|
20
|
+
export type RequestHeaders = <%~ (headers && headers.type) || '{}' %>;
|
|
21
|
+
export type ResponseBody = <%~ route.response.type %>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<%
|
|
2
|
+
const { contract, utils } = it;
|
|
3
|
+
const { formatDescription, require, _ } = utils;
|
|
4
|
+
|
|
5
|
+
%>
|
|
6
|
+
<% if (contract.$content.length) { %>
|
|
7
|
+
export type <%~ contract.name %> = {
|
|
8
|
+
<% _.forEach(contract.$content, (field) => { %>
|
|
9
|
+
<%~ includeFile('@base/object-field-jsdoc.ejs', { ...it, field }) %>
|
|
10
|
+
<%~ field.field %>;
|
|
11
|
+
<% }) %>
|
|
12
|
+
}<%~ utils.isNeedToAddNull(contract) ? ' | null' : ''%>
|
|
13
|
+
<% } else { %>
|
|
14
|
+
export type <%~ contract.name %> = Record<string, any>;
|
|
15
|
+
<% } %>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<%
|
|
2
|
+
const { apiConfig, routes, utils, config } = it;
|
|
3
|
+
const { info, servers, externalDocs } = apiConfig;
|
|
4
|
+
const { _, require, formatDescription } = utils;
|
|
5
|
+
|
|
6
|
+
const server = (servers && servers[0]) || { url: "" };
|
|
7
|
+
|
|
8
|
+
const descriptionLines = _.compact([
|
|
9
|
+
`@title ${info.title || "No title"}`,
|
|
10
|
+
info.version && `@version ${info.version}`,
|
|
11
|
+
info.license && `@license ${_.compact([
|
|
12
|
+
info.license.name,
|
|
13
|
+
info.license.url && `(${info.license.url})`,
|
|
14
|
+
]).join(" ")}`,
|
|
15
|
+
info.termsOfService && `@termsOfService ${info.termsOfService}`,
|
|
16
|
+
server.url && `@baseUrl ${server.url}`,
|
|
17
|
+
externalDocs.url && `@externalDocs ${externalDocs.url}`,
|
|
18
|
+
info.contact && `@contact ${_.compact([
|
|
19
|
+
info.contact.name,
|
|
20
|
+
info.contact.email && `<${info.contact.email}>`,
|
|
21
|
+
info.contact.url && `(${info.contact.url})`,
|
|
22
|
+
]).join(" ")}`,
|
|
23
|
+
info.description && " ",
|
|
24
|
+
info.description && _.replace(formatDescription(info.description), /\n/g, "\n * "),
|
|
25
|
+
]);
|
|
26
|
+
|
|
27
|
+
%>
|
|
28
|
+
|
|
29
|
+
<% if (config.httpClientType === config.constants.HTTP_CLIENT.AXIOS) { %> import { AxiosRequestConfig, AxiosResponse } from "axios"; <% } %>
|
|
30
|
+
|
|
31
|
+
<% if (descriptionLines.length) { %>
|
|
32
|
+
/**
|
|
33
|
+
<% descriptionLines.forEach((descriptionLine) => { %>
|
|
34
|
+
* <%~ descriptionLine %>
|
|
35
|
+
|
|
36
|
+
<% }) %>
|
|
37
|
+
*/
|
|
38
|
+
<% } %>
|
|
39
|
+
export class <%~ config.apiClassName %><SecurityDataType extends unknown><% if (!config.singleHttpClient) { %> extends HttpClient<SecurityDataType> <% } %> {
|
|
40
|
+
|
|
41
|
+
<% if(config.singleHttpClient) { %>
|
|
42
|
+
http: HttpClient<SecurityDataType>;
|
|
43
|
+
|
|
44
|
+
constructor (http: HttpClient<SecurityDataType>) {
|
|
45
|
+
this.http = http;
|
|
46
|
+
}
|
|
47
|
+
<% } %>
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
<% routes.outOfModule && routes.outOfModule.forEach((route) => { %>
|
|
51
|
+
|
|
52
|
+
<%~ includeFile('./procedure-call.ejs', { ...it, route }) %>
|
|
53
|
+
|
|
54
|
+
<% }) %>
|
|
55
|
+
|
|
56
|
+
<% routes.combined && routes.combined.forEach(({ routes = [], moduleName }) => { %>
|
|
57
|
+
<%~ moduleName %> = {
|
|
58
|
+
<% routes.forEach((route) => { %>
|
|
59
|
+
|
|
60
|
+
<%~ includeFile('./procedure-call.ejs', { ...it, route }) %>
|
|
61
|
+
|
|
62
|
+
<% }) %>
|
|
63
|
+
}
|
|
64
|
+
<% }) %>
|
|
65
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
<%
|
|
2
|
+
const { utils, route, config } = it;
|
|
3
|
+
const { requestBodyInfo, responseBodyInfo, specificArgNameResolver } = route;
|
|
4
|
+
const { _, getInlineParseContent, getParseContent, parseSchema, getComponentByRef, require } = utils;
|
|
5
|
+
const { parameters, path, method, payload, query, formData, security, requestParams } = route.request;
|
|
6
|
+
const { type, errorType, contentTypes } = route.response;
|
|
7
|
+
const { HTTP_CLIENT, RESERVED_REQ_PARAMS_ARG_NAMES } = config.constants;
|
|
8
|
+
const routeDocs = includeFile("@base/route-docs", { config, route, utils });
|
|
9
|
+
const queryName = (query && query.name) || "query";
|
|
10
|
+
const pathParams = _.values(parameters);
|
|
11
|
+
const pathParamsNames = _.map(pathParams, "name");
|
|
12
|
+
|
|
13
|
+
const isFetchTemplate = config.httpClientType === HTTP_CLIENT.FETCH;
|
|
14
|
+
|
|
15
|
+
const requestConfigParam = {
|
|
16
|
+
name: specificArgNameResolver.resolve(RESERVED_REQ_PARAMS_ARG_NAMES),
|
|
17
|
+
optional: true,
|
|
18
|
+
type: "RequestParams",
|
|
19
|
+
defaultValue: "{}",
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const argToTmpl = ({ name, optional, type, defaultValue }) => `${name}${!defaultValue && optional ? '?' : ''}: ${type}${defaultValue ? ` = ${defaultValue}` : ''}`;
|
|
23
|
+
|
|
24
|
+
const rawWrapperArgs = config.extractRequestParams ?
|
|
25
|
+
_.compact([
|
|
26
|
+
requestParams && {
|
|
27
|
+
name: pathParams.length ? `{ ${_.join(pathParamsNames, ", ")}, ...${queryName} }` : queryName,
|
|
28
|
+
optional: false,
|
|
29
|
+
type: getInlineParseContent(requestParams),
|
|
30
|
+
},
|
|
31
|
+
...(!requestParams ? pathParams : []),
|
|
32
|
+
payload,
|
|
33
|
+
requestConfigParam,
|
|
34
|
+
]) :
|
|
35
|
+
_.compact([
|
|
36
|
+
...pathParams,
|
|
37
|
+
query,
|
|
38
|
+
payload,
|
|
39
|
+
requestConfigParam,
|
|
40
|
+
])
|
|
41
|
+
|
|
42
|
+
const wrapperArgs = _
|
|
43
|
+
// Sort by optionality
|
|
44
|
+
.sortBy(rawWrapperArgs, [o => o.optional])
|
|
45
|
+
.map(argToTmpl)
|
|
46
|
+
.join(', ')
|
|
47
|
+
|
|
48
|
+
// RequestParams["type"]
|
|
49
|
+
const requestContentKind = {
|
|
50
|
+
"JSON": "ContentType.Json",
|
|
51
|
+
"URL_ENCODED": "ContentType.UrlEncoded",
|
|
52
|
+
"FORM_DATA": "ContentType.FormData",
|
|
53
|
+
"TEXT": "ContentType.Text",
|
|
54
|
+
}
|
|
55
|
+
// RequestParams["format"]
|
|
56
|
+
const responseContentKind = {
|
|
57
|
+
"JSON": '"json"',
|
|
58
|
+
"IMAGE": '"blob"',
|
|
59
|
+
"FORM_DATA": isFetchTemplate ? '"formData"' : '"document"'
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const bodyTmpl = _.get(payload, "name") || null;
|
|
63
|
+
const queryTmpl = (query != null && queryName) || null;
|
|
64
|
+
const bodyContentKindTmpl = requestContentKind[requestBodyInfo.contentKind] || null;
|
|
65
|
+
const responseFormatTmpl = responseContentKind[responseBodyInfo.success && responseBodyInfo.success.schema && responseBodyInfo.success.schema.contentKind] || null;
|
|
66
|
+
const securityTmpl = security ? 'true' : null;
|
|
67
|
+
|
|
68
|
+
const describeReturnType = () => {
|
|
69
|
+
if (!config.toJS) return "";
|
|
70
|
+
|
|
71
|
+
switch(config.httpClientType) {
|
|
72
|
+
case HTTP_CLIENT.AXIOS: {
|
|
73
|
+
return `Promise<AxiosResponse<${type}>>`
|
|
74
|
+
}
|
|
75
|
+
default: {
|
|
76
|
+
return `Promise<HttpResponse<${type}, ${errorType}>`
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
%>
|
|
82
|
+
/**
|
|
83
|
+
<%~ routeDocs.description %>
|
|
84
|
+
|
|
85
|
+
*<% /* Here you can add some other JSDoc tags */ %>
|
|
86
|
+
|
|
87
|
+
<%~ routeDocs.lines %>
|
|
88
|
+
|
|
89
|
+
*/
|
|
90
|
+
<%~ route.routeName.usage %><%~ route.namespace ? ': ' : ' = ' %>(<%~ wrapperArgs %>)<%~ config.toJS ? `: ${describeReturnType()}` : "" %> =>
|
|
91
|
+
<%~ config.singleHttpClient ? 'this.http.request' : 'this.request' %><<%~ type %>, <%~ errorType %>>({
|
|
92
|
+
path: `<%~ path %>`,
|
|
93
|
+
method: '<%~ _.upperCase(method) %>',
|
|
94
|
+
<%~ queryTmpl ? `query: ${queryTmpl},` : '' %>
|
|
95
|
+
<%~ bodyTmpl ? `body: ${bodyTmpl},` : '' %>
|
|
96
|
+
<%~ securityTmpl ? `secure: ${securityTmpl},` : '' %>
|
|
97
|
+
<%~ bodyContentKindTmpl ? `type: ${bodyContentKindTmpl},` : '' %>
|
|
98
|
+
<%~ responseFormatTmpl ? `format: ${responseFormatTmpl},` : '' %>
|
|
99
|
+
...<%~ _.get(requestConfigParam, "name") %>,
|
|
100
|
+
})<%~ route.namespace ? ',' : '' %>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<%
|
|
2
|
+
const { utils, config, routes, modelTypes } = it;
|
|
3
|
+
const { _, pascalCase } = utils;
|
|
4
|
+
const dataContracts = config.modular ? _.map(modelTypes, "name") : [];
|
|
5
|
+
%>
|
|
6
|
+
|
|
7
|
+
<% if (dataContracts.length) { %>
|
|
8
|
+
import { <%~ dataContracts.join(", ") %> } from "./<%~ config.fileNames.dataContracts %>"
|
|
9
|
+
<% } %>
|
|
10
|
+
|
|
11
|
+
<%
|
|
12
|
+
/* TODO: outOfModule, combined should be attributes of route, which will allow to avoid duplication of code */
|
|
13
|
+
%>
|
|
14
|
+
|
|
15
|
+
<% routes.outOfModule && routes.outOfModule.forEach(({ routes = [] }) => { %>
|
|
16
|
+
<% routes.forEach((route) => { %>
|
|
17
|
+
<%~ includeFile('@base/route-type.ejs', { ...it, route }) %>
|
|
18
|
+
<% }) %>
|
|
19
|
+
<% }) %>
|
|
20
|
+
|
|
21
|
+
<% routes.combined && routes.combined.forEach(({ routes = [], moduleName }) => { %>
|
|
22
|
+
export namespace <%~ pascalCase(moduleName) %> {
|
|
23
|
+
<% routes.forEach((route) => { %>
|
|
24
|
+
<%~ includeFile('@base/route-type.ejs', { ...it, route }) %>
|
|
25
|
+
<% }) %>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
<% }) %>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<%
|
|
2
|
+
const { utils, route, config, modelTypes } = it;
|
|
3
|
+
const { _, pascalCase, require } = utils;
|
|
4
|
+
const apiClassName = pascalCase(route.moduleName);
|
|
5
|
+
const routes = route.routes;
|
|
6
|
+
const dataContracts = _.map(modelTypes, "name");
|
|
7
|
+
%>
|
|
8
|
+
|
|
9
|
+
<% if (config.httpClientType === config.constants.HTTP_CLIENT.AXIOS) { %> import { AxiosRequestConfig, AxiosResponse } from "axios"; <% } %>
|
|
10
|
+
|
|
11
|
+
import { HttpClient, RequestParams, ContentType, HttpResponse } from "./<%~ config.fileNames.httpClient %>";
|
|
12
|
+
<% if (dataContracts.length) { %>
|
|
13
|
+
import { <%~ dataContracts.join(", ") %> } from "./<%~ config.fileNames.dataContracts %>"
|
|
14
|
+
<% } %>
|
|
15
|
+
|
|
16
|
+
export class <%= apiClassName %><SecurityDataType = unknown><% if (!config.singleHttpClient) { %> extends HttpClient<SecurityDataType> <% } %> {
|
|
17
|
+
<% if(config.singleHttpClient) { %>
|
|
18
|
+
http: HttpClient<SecurityDataType>;
|
|
19
|
+
|
|
20
|
+
constructor (http: HttpClient<SecurityDataType>) {
|
|
21
|
+
this.http = http;
|
|
22
|
+
}
|
|
23
|
+
<% } %>
|
|
24
|
+
|
|
25
|
+
<% routes.forEach((route) => { %>
|
|
26
|
+
<%~ includeFile('./procedure-call.ejs', { ...it, route }) %>
|
|
27
|
+
<% }) %>
|
|
28
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
<%
|
|
2
|
+
const { utils, route, config } = it;
|
|
3
|
+
const { requestBodyInfo, responseBodyInfo, specificArgNameResolver } = route;
|
|
4
|
+
const { _, getInlineParseContent, getParseContent, parseSchema, getComponentByRef, require } = utils;
|
|
5
|
+
const { parameters, path, method, payload, query, formData, security, requestParams } = route.request;
|
|
6
|
+
const { type, errorType, contentTypes } = route.response;
|
|
7
|
+
const { HTTP_CLIENT, RESERVED_REQ_PARAMS_ARG_NAMES } = config.constants;
|
|
8
|
+
const routeDocs = includeFile("@base/route-docs", { config, route, utils });
|
|
9
|
+
const queryName = (query && query.name) || "query";
|
|
10
|
+
const pathParams = _.values(parameters);
|
|
11
|
+
const pathParamsNames = _.map(pathParams, "name");
|
|
12
|
+
|
|
13
|
+
const isFetchTemplate = config.httpClientType === HTTP_CLIENT.FETCH;
|
|
14
|
+
|
|
15
|
+
const requestConfigParam = {
|
|
16
|
+
name: specificArgNameResolver.resolve(RESERVED_REQ_PARAMS_ARG_NAMES),
|
|
17
|
+
optional: true,
|
|
18
|
+
type: "RequestParams",
|
|
19
|
+
defaultValue: "{}",
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const argToTmpl = ({ name, optional, type, defaultValue }) => `${name}${!defaultValue && optional ? '?' : ''}: ${type}${defaultValue ? ` = ${defaultValue}` : ''}`;
|
|
23
|
+
|
|
24
|
+
const rawWrapperArgs = config.extractRequestParams ?
|
|
25
|
+
_.compact([
|
|
26
|
+
requestParams && {
|
|
27
|
+
name: pathParams.length ? `{ ${_.join(pathParamsNames, ", ")}, ...${queryName} }` : queryName,
|
|
28
|
+
optional: false,
|
|
29
|
+
type: getInlineParseContent(requestParams),
|
|
30
|
+
},
|
|
31
|
+
...(!requestParams ? pathParams : []),
|
|
32
|
+
payload,
|
|
33
|
+
requestConfigParam,
|
|
34
|
+
]) :
|
|
35
|
+
_.compact([
|
|
36
|
+
...pathParams,
|
|
37
|
+
query,
|
|
38
|
+
payload,
|
|
39
|
+
requestConfigParam,
|
|
40
|
+
])
|
|
41
|
+
|
|
42
|
+
const wrapperArgs = _
|
|
43
|
+
// Sort by optionality
|
|
44
|
+
.sortBy(rawWrapperArgs, [o => o.optional])
|
|
45
|
+
.map(argToTmpl)
|
|
46
|
+
.join(', ')
|
|
47
|
+
|
|
48
|
+
// RequestParams["type"]
|
|
49
|
+
const requestContentKind = {
|
|
50
|
+
"JSON": "ContentType.Json",
|
|
51
|
+
"URL_ENCODED": "ContentType.UrlEncoded",
|
|
52
|
+
"FORM_DATA": "ContentType.FormData",
|
|
53
|
+
"TEXT": "ContentType.Text",
|
|
54
|
+
}
|
|
55
|
+
// RequestParams["format"]
|
|
56
|
+
const responseContentKind = {
|
|
57
|
+
"JSON": '"json"',
|
|
58
|
+
"IMAGE": '"blob"',
|
|
59
|
+
"FORM_DATA": isFetchTemplate ? '"formData"' : '"document"'
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const bodyTmpl = _.get(payload, "name") || null;
|
|
63
|
+
const queryTmpl = (query != null && queryName) || null;
|
|
64
|
+
const bodyContentKindTmpl = requestContentKind[requestBodyInfo.contentKind] || null;
|
|
65
|
+
const responseFormatTmpl = responseContentKind[responseBodyInfo.success && responseBodyInfo.success.schema && responseBodyInfo.success.schema.contentKind] || null;
|
|
66
|
+
const securityTmpl = security ? 'true' : null;
|
|
67
|
+
|
|
68
|
+
const describeReturnType = () => {
|
|
69
|
+
if (!config.toJS) return "";
|
|
70
|
+
|
|
71
|
+
switch(config.httpClientType) {
|
|
72
|
+
case HTTP_CLIENT.AXIOS: {
|
|
73
|
+
return `Promise<AxiosResponse<${type}>>`
|
|
74
|
+
}
|
|
75
|
+
default: {
|
|
76
|
+
return `Promise<HttpResponse<${type}, ${errorType}>`
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
%>
|
|
82
|
+
/**
|
|
83
|
+
<%~ routeDocs.description %>
|
|
84
|
+
|
|
85
|
+
*<% /* Here you can add some other JSDoc tags */ %>
|
|
86
|
+
|
|
87
|
+
<%~ routeDocs.lines %>
|
|
88
|
+
|
|
89
|
+
*/
|
|
90
|
+
<%~ route.routeName.usage %> = (<%~ wrapperArgs %>)<%~ config.toJS ? `: ${describeReturnType()}` : "" %> =>
|
|
91
|
+
<%~ config.singleHttpClient ? 'this.http.request' : 'this.request' %><<%~ type %>, <%~ errorType %>>({
|
|
92
|
+
path: `<%~ path %>`,
|
|
93
|
+
method: '<%~ _.upperCase(method) %>',
|
|
94
|
+
<%~ queryTmpl ? `query: ${queryTmpl},` : '' %>
|
|
95
|
+
<%~ bodyTmpl ? `body: ${bodyTmpl},` : '' %>
|
|
96
|
+
<%~ securityTmpl ? `secure: ${securityTmpl},` : '' %>
|
|
97
|
+
<%~ bodyContentKindTmpl ? `type: ${bodyContentKindTmpl},` : '' %>
|
|
98
|
+
<%~ responseFormatTmpl ? `format: ${responseFormatTmpl},` : '' %>
|
|
99
|
+
...<%~ _.get(requestConfigParam, "name") %>,
|
|
100
|
+
})
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<%
|
|
2
|
+
const { utils, config, route, modelTypes } = it;
|
|
3
|
+
const { _, pascalCase } = utils;
|
|
4
|
+
const { routes, moduleName } = route;
|
|
5
|
+
const dataContracts = config.modular ? _.map(modelTypes, "name") : [];
|
|
6
|
+
|
|
7
|
+
%>
|
|
8
|
+
<% if (dataContracts.length) { %>
|
|
9
|
+
import { <%~ dataContracts.join(", ") %> } from "./<%~ config.fileNames.dataContracts %>"
|
|
10
|
+
<% } %>
|
|
11
|
+
|
|
12
|
+
export namespace <%~ pascalCase(moduleName) %> {
|
|
13
|
+
<% _.forEach(routes, (route) => { %>
|
|
14
|
+
|
|
15
|
+
<%~ includeFile('@base/route-type.ejs', { ...it, route }) %>
|
|
16
|
+
|
|
17
|
+
<% }) %>
|
|
18
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export const paramsSerializerBy =
|
|
2
|
+
(
|
|
3
|
+
format?: Partial<
|
|
4
|
+
Record<
|
|
5
|
+
(string & {}) | '_default',
|
|
6
|
+
'brackets' | 'repeat' | 'indices' | 'comma'
|
|
7
|
+
>
|
|
8
|
+
>,
|
|
9
|
+
options?: {
|
|
10
|
+
decoded?: boolean;
|
|
11
|
+
},
|
|
12
|
+
) =>
|
|
13
|
+
(params: Record<string, any>) => {
|
|
14
|
+
const serialized = Object.entries(params)
|
|
15
|
+
.reduce<string[]>((acc, [key, value]) => {
|
|
16
|
+
const isArray = Array.isArray(value);
|
|
17
|
+
if (!isArray) {
|
|
18
|
+
return acc.concat(`${key}=${params[key]}`);
|
|
19
|
+
}
|
|
20
|
+
const asRepeat = (v: string) => `${key}=${v}`;
|
|
21
|
+
const asBracket = (v: string) => `${key}[]=${v}`;
|
|
22
|
+
const asIndices = (v: string, idx: number) => `${key}[${idx}]=${v}`;
|
|
23
|
+
|
|
24
|
+
switch (format?.[key] || format?._default) {
|
|
25
|
+
case 'repeat':
|
|
26
|
+
return acc.concat(value.map(asRepeat).join('&'));
|
|
27
|
+
case 'brackets':
|
|
28
|
+
return acc.concat(value.map(asBracket).join('&'));
|
|
29
|
+
case 'indices':
|
|
30
|
+
return acc.concat(value.map(asIndices).join('&'));
|
|
31
|
+
default: // comma
|
|
32
|
+
return acc.concat(`${key}=${value.join(',')}`);
|
|
33
|
+
}
|
|
34
|
+
}, [])
|
|
35
|
+
.join('&');
|
|
36
|
+
|
|
37
|
+
if (options?.decoded === true) {
|
|
38
|
+
return decodeURIComponent(serialized);
|
|
39
|
+
}
|
|
40
|
+
return serialized;
|
|
41
|
+
};
|