Skip to content

Commit 019d4bb

Browse files
Merge pull request #278 from openapi-ui/main
feat: support custom templates
2 parents b977c3f + d30dcd3 commit 019d4bb

File tree

9 files changed

+235
-153
lines changed

9 files changed

+235
-153
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

README-en_US.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,17 +262,22 @@ openapi -i ./spec.json -o ./apis
262262
| customClassName | (tagName: string) => string | custom tag name |
263263
| customType | ({<br>schemaObject: SchemaObject \| ReferenceObject,<br>namespace: string,<br>originGetType:(schemaObject: SchemaObject \| ReferenceObject, namespace: string, schemas?: ComponentsObject['schemas']) => string,<br>schemas?: ComponentsObject['schemas'],<br>}) => string | custom type <br> _returning a non-string will use the default method to get the type_ |
264264
| customFileNames | (<br>operationObject: OperationObject,<br>apiPath: string,<br>apiMethod: string,<br>) => string[] | custom generate request client controller file name, can return multiple: generate multiple files. <br> _if the return value is empty, the default getFileNames is used_ |
265+
| customTemplates | {<br>[TypescriptFileType.serviceController]?: <T, U>(item: T, context: U) => string;<br>} | custom template, details see source code |
265266

266267
## Apifox-Config
267268

268269
| attribute | type | description | required |
269270
| --- | --- | --- | --- |
270271
| projectId | string | project id | true |
272+
| apifoxToken | string | [get](https://docs.apifox.com/doc-5723694) | true |
271273
| local | string | language(default:zh-CN) | false |
272274
| apifoxVersion | string | default: 2024-03-28, [current apifox version](https://api.apifox.com/v1/versions) | false |
273275
| includeTags | \* or string[] | default: \* | false |
274276
| excludeTags | string[] | default: [] | false |
275-
| apifoxToken | string | [get](https://docs.apifox.com/doc-5723694) | true |
277+
| oasVersion | string | specify the version of the OpenAPI specification used for export, can have values such as "2.0", "3.0" or "3.1" | '3.0' |
278+
| exportFormat | string | specify the format of the exported OpenAPI file, can have values such as 'JSON' or 'YAML' | 'JSON' |
279+
| includeApifoxExtensionProperties | boolean | specify whether to include the OpenAPI specification extension fields `x-apifox` | false |
280+
| addFoldersToTags | boolean | specify whether to include the directory name of the interface in the tag field | false |
276281

277282
## JSON Schemas
278283

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,17 +264,22 @@ openapi --i ./spec.json --o ./apis
264264
| customClassName | (tagName: string) => string | 自定义标签名 |
265265
| customType | ({<br>schemaObject: SchemaObject \| ReferenceObject,<br>namespace: string,<br>originGetType:(schemaObject: SchemaObject \| ReferenceObject, namespace: string, schemas?: ComponentsObject['schemas']) => string,<br>schemas?: ComponentsObject['schemas'],<br>}) => string | 自定义类型 <br> _返回非字符串将使用默认方法获取type_ |
266266
| customFileNames | (<br>operationObject: OperationObject,<br>apiPath: string,<br>apiMethod: string,<br>) => string[] | 自定义生成的请求客户端文件名称,可以返回多个文件名称的数组(表示生成多个文件). <br> _返回为空,则使用默认的方法获取_ |
267+
| customTemplates | {<br>[TypescriptFileType.serviceController]?: <T, U>(item: T, context: U) => string;<br>} | 自定义模板,详情请看源码 |
267268

268269
## Apifox-Config
269270

270271
| 属性 | 类型 | 说明 | 必填 |
271272
| --- | --- | --- | --- |
272273
| projectId | string | 项目id | true |
273-
| local | string | 语言(默认:zh-CN) | false |
274+
| apifoxToken | string | [获取](https://docs.apifox.com/doc-5723694) | true |
275+
| local | string | 语言(默认: zh-CN) | false |
274276
| apifoxVersion | string | 默认: 2024-03-28, [获取当前版本](https://api.apifox.com/v1/versions) | false |
275277
| includeTags | \* 或 string[] | 默认: \* | false |
276278
| excludeTags | string[] | 默认: [] | false |
277-
| apifoxToken | string | [获取](https://docs.apifox.com/doc-5723694) | true |
279+
| oasVersion | string | 指定用于导出的 OpenAPI 规范的版本,可以有值如 "2.0"、"3.0"、"3.1" | '3.0' |
280+
| exportFormat | string | 指定导出的 OpenAPI 文件的格式,可以有值如 'JSON' 或 'YAML' | 'JSON' |
281+
| includeApifoxExtensionProperties | boolean | 指定是否包含 Apifox 的 OpenAPI 规范扩展字段 `x-apifox` | false |
282+
| addFoldersToTags | boolean | 指定是否在标签字段中包含接口的目录名称 | false |
278283

279284
## JSON Schemas
280285

src/generator/serviceGenarator.ts

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ import {
7070
ICustomSchemaObject,
7171
IPropObject,
7272
ISchemaItem,
73+
IServiceControllerPayload,
7374
ITypeItem,
7475
ITypescriptFileType,
7576
type MergeOption,
@@ -329,18 +330,39 @@ export default class ServiceGenerator {
329330

330331
// 生成 service controller 文件
331332
this.getServiceTPConfigs().forEach((tp) => {
333+
const { list, ...restTp } = tp;
334+
const payload: Omit<typeof tp, 'list'> &
335+
IServiceControllerPayload<typeof list> = {
336+
namespace: this.config.namespace,
337+
requestOptionsType: this.config.requestOptionsType,
338+
requestImportStatement: this.config.requestImportStatement,
339+
interfaceFileName: interfaceFileName,
340+
list,
341+
...restTp,
342+
};
343+
const hookCustomTemplateService =
344+
this.config.hook?.customTemplates?.[
345+
TypescriptFileType.serviceController
346+
];
347+
348+
if (hookCustomTemplateService) {
349+
payload.list = list.map((item) => {
350+
return {
351+
customTemplate: true,
352+
data: hookCustomTemplateService<typeof item, typeof payload>(
353+
item,
354+
payload
355+
),
356+
};
357+
});
358+
}
359+
332360
const hasError = this.genFileFromTemplate(
333361
isGenJavaScript
334362
? getFinalFileName(`${tp.className}.js`)
335363
: getFinalFileName(`${tp.className}.ts`),
336364
TypescriptFileType.serviceController,
337-
{
338-
namespace: this.config.namespace,
339-
requestOptionsType: this.config.requestOptionsType,
340-
requestImportStatement: this.config.requestImportStatement,
341-
interfaceFileName: interfaceFileName,
342-
...tp,
343-
}
365+
payload
344366
);
345367

346368
prettierError.push(hasError);

src/generator/type.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,16 @@ type MergerOptionProps = {
6969
};
7070

7171
export type MergerOptions = MergeOption & Partial<MergerOptionProps>;
72+
73+
export type IServiceControllerPayload<T> = {
74+
namespace: string;
75+
requestOptionsType: string;
76+
requestImportStatement: string;
77+
interfaceFileName: string;
78+
list:
79+
| {
80+
customTemplate: boolean;
81+
data: string;
82+
}[]
83+
| T;
84+
};

src/index.ts

Lines changed: 13 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,18 @@ export type GenerateServiceProps = {
233234
apiPath: string,
234235
apiMethod: string
235236
) => string[] | null;
237+
/**
238+
* 自定义模板
239+
*/
240+
customTemplates?: {
241+
/**
242+
* 自定义 serviceController 模板
243+
*/
244+
[TypescriptFileType.serviceController]?: <T, U>(
245+
item: T,
246+
context: U
247+
) => string;
248+
};
236249
};
237250
};
238251

src/readConfig.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ export const readConfig = async <T = unknown>({
2626
} else {
2727
return (await explorerSync.search()?.config) as T;
2828
}
29-
// eslint-disable-next-line no-unused-vars
3029
} catch (error) {
3130
return undefined;
3231
}

0 commit comments

Comments
 (0)