Skip to content

Commit e404129

Browse files
Autumnshilei
andauthored
feat: support custom templates (#274)
* feat: support custom templates * feat: support custom templates --------- Co-authored-by: lei <sgbkee@163.com>
1 parent 9155982 commit e404129

File tree

5 files changed

+202
-149
lines changed

5 files changed

+202
-149
lines changed

.changeset/icy-candles-wear.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'openapi-ts-request': patch
3+
---
4+
5+
feat: support custom templates

src/generator/serviceGenarator.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -329,18 +329,36 @@ export default class ServiceGenerator {
329329

330330
// 生成 service controller 文件
331331
this.getServiceTPConfigs().forEach((tp) => {
332+
const { list, ...restTp } = tp;
333+
const payload: Record<string, any> = {
334+
namespace: this.config.namespace,
335+
requestOptionsType: this.config.requestOptionsType,
336+
requestImportStatement: this.config.requestImportStatement,
337+
interfaceFileName: interfaceFileName,
338+
...restTp,
339+
};
340+
341+
const hookCustomTemplateService =
342+
this.config.hook?.customTemplates?.[
343+
TypescriptFileType.serviceController
344+
];
345+
if (hookCustomTemplateService) {
346+
payload.list = list.map((item) => {
347+
return {
348+
customTemplate: true,
349+
data: hookCustomTemplateService(item, payload),
350+
};
351+
});
352+
} else {
353+
payload.list = list;
354+
}
355+
332356
const hasError = this.genFileFromTemplate(
333357
isGenJavaScript
334358
? getFinalFileName(`${tp.className}.js`)
335359
: getFinalFileName(`${tp.className}.ts`),
336360
TypescriptFileType.serviceController,
337-
{
338-
namespace: this.config.namespace,
339-
requestOptionsType: this.config.requestOptionsType,
340-
requestImportStatement: this.config.requestImportStatement,
341-
interfaceFileName: interfaceFileName,
342-
...tp,
343-
}
361+
payload
344362
);
345363

346364
prettierError.push(hasError);

src/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { isEmpty, map } from 'lodash';
22

33
import { PriorityRule, ReactQueryMode } from './config';
4+
import { TypescriptFileType } from './generator/config';
45
import { mockGenerator } from './generator/mockGenarator';
56
import ServiceGenerator from './generator/serviceGenarator';
67
import { APIDataType } from './generator/type';
@@ -233,6 +234,15 @@ export type GenerateServiceProps = {
233234
apiPath: string,
234235
apiMethod: string
235236
) => string[] | null;
237+
/**
238+
* 自定义模板
239+
*/
240+
customTemplates?: {
241+
/**
242+
* 自定义 serviceController 模板
243+
*/
244+
[TypescriptFileType.serviceController]?: (item: any, ctx: any) => string;
245+
};
236246
};
237247
};
238248

templates/serviceController.njk

Lines changed: 145 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -8,166 +8,169 @@
88
{% endif %}
99

1010
{% for api in list -%}
11-
/** {{ api.desc if api.desc else '此处后端没有提供注释' }} {{ api.method | upper }} {{ api.pathInComment | safe }}{{ ' ' if api.apifoxRunLink else '' }}{{ api.apifoxRunLink }} */
12-
export async function {{ api.functionName }}({
13-
{%- if api.params and api.hasParams %}
14-
params
15-
{%- if api.hasParams -%}
16-
{{ "," if api.body or api.file }}
17-
{%- endif -%}
18-
{%- endif -%}
19-
{%- if api.body -%}
20-
body
21-
{{ "," if api.file }}
22-
{%- endif %}
23-
{%- if api.file -%}
24-
{%- for file in api.file -%}
25-
{{ file.title | safe }}
26-
{{ "," if not loop.last }}
27-
{%- endfor -%}
28-
{%- endif -%}
29-
{{ "," if api.body or api.hasParams or api.file }}
30-
options
31-
}
32-
{%- if genType === "ts" -%}
33-
: {
11+
{% if api.customTemplate %}
12+
{{ api.data }}
13+
{% else %}
14+
/** {{ api.desc if api.desc else '此处后端没有提供注释' }} {{ api.method | upper }} {{ api.pathInComment | safe }}{{ ' ' if api.apifoxRunLink else '' }}{{ api.apifoxRunLink }} */
15+
export async function {{ api.functionName }}({
3416
{%- if api.params and api.hasParams %}
35-
// 叠加生成的Param类型 (非body参数openapi默认没有生成对象)
36-
params: {{ namespace }}.{{ api.typeName }}
37-
{# header 入参 -#}
38-
{% if api.params.header -%}
39-
& { // header
40-
{% for param in api.params.header -%}
41-
{% if param.description -%}
42-
/** {{ param.description }} */
43-
{% endif -%}
44-
'{{ param.name }}'
45-
{{- "?" if not param.required }}
46-
{{- (": " + param.type + ";") | safe }}
47-
{% endfor -%}
48-
}
49-
{%- endif -%}
17+
params
5018
{%- if api.hasParams -%}
51-
{{ ";" if api.body or api.file }}
19+
{{ "," if api.body or api.file }}
5220
{%- endif -%}
5321
{%- endif -%}
54-
5522
{%- if api.body -%}
56-
body:
57-
{% if api.body.propertiesList %}
58-
{
59-
{%- for prop in api.body.propertiesList %}
60-
{% if prop.schema.description -%}
61-
/** {{ prop.schema.description }} */
62-
{% endif -%}
63-
'{{ prop.key }}'{{ "?" if not prop.schema.required }}: {{ prop.schema.type }},
64-
{%- endfor %}
65-
}
66-
{%- else -%}
67-
{{ api.body.type }}
68-
{%- endif -%}
69-
{{ ";" if api.file }}
23+
body
24+
{{ "," if api.file }}
7025
{%- endif %}
71-
7226
{%- if api.file -%}
7327
{%- for file in api.file -%}
7428
{{ file.title | safe }}
75-
{{- "?" if not api.file.required -}}
76-
: File {{ "[]" if file.multiple }}
77-
{{ ";" if not loop.last }}
29+
{{ "," if not loop.last }}
7830
{%- endfor -%}
7931
{%- endif -%}
80-
{{ ";" if api.body or api.hasParams or api.file }}
81-
options?: {{ requestOptionsType }}
32+
{{ "," if api.body or api.hasParams or api.file }}
33+
options
8234
}
83-
{%- endif -%}
84-
)
85-
{
86-
{% if api.params and api.params.path %}
87-
const { {% for param in api.params.path %}'{{ param.name }}': {{ param.alias }}, {% endfor %}
88-
{% if api.params.path -%}
89-
...queryParams
90-
{% endif -%}
91-
} = params;
92-
{% endif %}
93-
{%- if api.hasFormData -%}
94-
const formData = new FormData();
35+
{%- if genType === "ts" -%}
36+
: {
37+
{%- if api.params and api.hasParams %}
38+
// 叠加生成的Param类型 (非body参数openapi默认没有生成对象)
39+
params: {{ namespace }}.{{ api.typeName }}
40+
{# header 入参 -#}
41+
{% if api.params.header -%}
42+
& { // header
43+
{% for param in api.params.header -%}
44+
{% if param.description -%}
45+
/** {{ param.description }} */
46+
{% endif -%}
47+
'{{ param.name }}'
48+
{{- "?" if not param.required }}
49+
{{- (": " + param.type + ";") | safe }}
50+
{% endfor -%}
51+
}
52+
{%- endif -%}
53+
{%- if api.hasParams -%}
54+
{{ ";" if api.body or api.file }}
55+
{%- endif -%}
56+
{%- endif -%}
57+
58+
{%- if api.body -%}
59+
body:
60+
{% if api.body.propertiesList %}
61+
{
62+
{%- for prop in api.body.propertiesList %}
63+
{% if prop.schema.description -%}
64+
/** {{ prop.schema.description }} */
65+
{% endif -%}
66+
'{{ prop.key }}'{{ "?" if not prop.schema.required }}: {{ prop.schema.type }},
67+
{%- endfor %}
68+
}
69+
{%- else -%}
70+
{{ api.body.type }}
71+
{%- endif -%}
72+
{{ ";" if api.file }}
73+
{%- endif %}
74+
75+
{%- if api.file -%}
76+
{%- for file in api.file -%}
77+
{{ file.title | safe }}
78+
{{- "?" if not api.file.required -}}
79+
: File {{ "[]" if file.multiple }}
80+
{{ ";" if not loop.last }}
81+
{%- endfor -%}
82+
{%- endif -%}
83+
{{ ";" if api.body or api.hasParams or api.file }}
84+
options?: {{ requestOptionsType }}
85+
}
86+
{%- endif -%}
87+
)
88+
{
89+
{% if api.params and api.params.path %}
90+
const { {% for param in api.params.path %}'{{ param.name }}': {{ param.alias }}, {% endfor %}
91+
{% if api.params.path -%}
92+
...queryParams
93+
{% endif -%}
94+
} = params;
95+
{% endif %}
96+
{%- if api.hasFormData -%}
97+
const formData = new FormData();
98+
99+
{% if api.file -%}
100+
{% for file in api.file %}
101+
if({{ file.title | safe }}) {
102+
{% if file.multiple %}
103+
{{ file.title | safe }}.forEach(f => formData.append('{{ file.title | safe }}', f || ''));
104+
{% else %}
105+
formData.append('{{ file.title | safe }}', {{ file.title | safe }})
106+
{% endif %}
107+
}
108+
{% endfor %}
109+
{%- endif -%}
95110

96-
{% if api.file -%}
97-
{% for file in api.file %}
98-
if({{ file.title | safe }}) {
99-
{% if file.multiple %}
100-
{{ file.title | safe }}.forEach(f => formData.append('{{ file.title | safe }}', f || ''));
111+
{% if api.body %}
112+
Object.keys(body).forEach(ele => {
113+
{% if genType === "ts" %}
114+
const item = (body as { [key: string]: any })[ele];
101115
{% else %}
102-
formData.append('{{ file.title | safe }}', {{ file.title | safe }})
116+
const item = body[ele];
103117
{% endif %}
104-
}
105-
{% endfor %}
106-
{%- endif -%}
107-
108-
{% if api.body %}
109-
Object.keys(body).forEach(ele => {
110-
{% if genType === "ts" %}
111-
const item = (body as { [key: string]: any })[ele];
112-
{% else %}
113-
const item = body[ele];
114-
{% endif %}
115-
if (item !== undefined && item !== null) {
116-
{% if genType === "ts" %}
117-
if (typeof item === 'object' && !(item instanceof File)) {
118-
if (item instanceof Array) {
119-
item.forEach((f) => formData.append(ele, f || ''));
118+
if (item !== undefined && item !== null) {
119+
{% if genType === "ts" %}
120+
if (typeof item === 'object' && !(item instanceof File)) {
121+
if (item instanceof Array) {
122+
item.forEach((f) => formData.append(ele, f || ''));
123+
} else {
124+
formData.append(ele, JSON.stringify(item));
125+
}
120126
} else {
121-
formData.append(ele, JSON.stringify(item));
127+
formData.append(ele, item);
122128
}
123-
} else {
124-
formData.append(ele, item);
125-
}
126-
{% else %}
127-
formData.append(ele, typeof item === 'object' ? JSON.stringify(item) : item);
128-
{% endif %}
129-
}
130-
});
129+
{% else %}
130+
formData.append(ele, typeof item === 'object' ? JSON.stringify(item) : item);
131+
{% endif %}
132+
}
133+
});
134+
{% endif %}
131135
{% endif %}
132-
{% endif %}
133136

134-
{% if api.hasPathVariables or api.hasApiPrefix -%}
135-
return request{{ ("<" + api.response.type + ">") | safe if genType === "ts" }}(`{{ api.path | safe }}`, {
136-
{% else -%}
137-
return request{{ ("<" + api.response.type + ">") | safe if genType === "ts" }}('{{ api.path }}', {
138-
{% endif -%}
139-
method: '{{ api.method | upper }}',
140-
{%- if api.hasHeader and api.body.mediaType %}
141-
headers: {
142-
{%- if api.body.mediaType %}
143-
'Content-Type': '{{ api.body.mediaType | safe }}',
144-
{%- endif %}
145-
},
146-
{%- endif %}
147-
{%- if api.params and api.hasParams %}
148-
params: {
149-
{%- for query in api.params.query %}
150-
{% if query.schema.default -%}
151-
// {{ query.name | safe }} has a default value: {{ query.schema.default | safe }}
152-
'{{ query.name | safe }}': '{{query.schema.default | safe}}',
153-
{%- endif -%}
154-
{%- endfor -%}
155-
...{{ 'queryParams' if api.params and api.params.path else 'params' }},
156-
{%- for query in api.params.query %}
157-
{%- if query.isComplexType %}
158-
'{{ query.name | safe }}': undefined,
159-
...{{ 'queryParams' if api.params and api.params.path else 'params' }}['{{ query.name | safe }}'],
137+
{% if api.hasPathVariables or api.hasApiPrefix -%}
138+
return request{{ ("<" + api.response.type + ">") | safe if genType === "ts" }}(`{{ api.path | safe }}`, {
139+
{% else -%}
140+
return request{{ ("<" + api.response.type + ">") | safe if genType === "ts" }}('{{ api.path }}', {
141+
{% endif -%}
142+
method: '{{ api.method | upper }}',
143+
{%- if api.hasHeader and api.body.mediaType %}
144+
headers: {
145+
{%- if api.body.mediaType %}
146+
'Content-Type': '{{ api.body.mediaType | safe }}',
160147
{%- endif %}
161-
{%- endfor -%}
162-
},
163-
{%- endif %}
164-
{%- if api.hasFormData %}
165-
data: formData,
166-
{%- elseif api.body %}
167-
data: body,
168-
{%- endif %}
169-
...(options || {{ api.options | dump }}),
170-
});
171-
}
172-
148+
},
149+
{%- endif %}
150+
{%- if api.params and api.hasParams %}
151+
params: {
152+
{%- for query in api.params.query %}
153+
{% if query.schema.default -%}
154+
// {{ query.name | safe }} has a default value: {{ query.schema.default | safe }}
155+
'{{ query.name | safe }}': '{{query.schema.default | safe}}',
156+
{%- endif -%}
157+
{%- endfor -%}
158+
...{{ 'queryParams' if api.params and api.params.path else 'params' }},
159+
{%- for query in api.params.query %}
160+
{%- if query.isComplexType %}
161+
'{{ query.name | safe }}': undefined,
162+
...{{ 'queryParams' if api.params and api.params.path else 'params' }}['{{ query.name | safe }}'],
163+
{%- endif %}
164+
{%- endfor -%}
165+
},
166+
{%- endif %}
167+
{%- if api.hasFormData %}
168+
data: formData,
169+
{%- elseif api.body %}
170+
data: body,
171+
{%- endif %}
172+
...(options || {{ api.options | dump }}),
173+
});
174+
}
175+
{% endif %}
173176
{% endfor -%}

0 commit comments

Comments
 (0)