Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/common-corners-walk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'openapi-ts-request': minor
---

feat: Added customRenderTemplateData hook functionality #512
1 change: 1 addition & 0 deletions README-en_US.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ openapi -i ./spec.json -o ./apis
| 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_ |
| 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_ |
| customTemplates | {<br>[TypescriptFileType.serviceController]?: <T, U>(item: T, context: U) => string;<br>} | custom template, details see source code |
| customRenderTemplateData | {<br>[TypescriptFileType]?: (list: any[], context: {fileName: string, params: Record<string, unknown>}) => any[]<br>} | custom list parameter processing during file generation, provides fine-grained control for different file types |

## Apifox-Config

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ openapi --i ./spec.json --o ./apis
| 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_ |
| customFileNames | (<br>operationObject: OperationObject,<br>apiPath: string,<br>apiMethod: string,<br>) => string[] | 自定义生成的请求客户端文件名称,可以返回多个文件名称的数组(表示生成多个文件). <br> _返回为空,则使用默认的方法获取_ |
| customTemplates | {<br>[TypescriptFileType.serviceController]?: <T, U>(item: T, context: U) => string;<br>} | 自定义模板,详情请看源码 |
| customRenderTemplateData | {<br>[TypescriptFileType]?: (list: any[], context: {fileName: string, params: Record<string, unknown>}) => any[]<br>} | 自定义文件生成时的 list 参数处理,支持对不同文件类型进行精细化控制 |

## Apifox-Config

Expand Down
98 changes: 96 additions & 2 deletions src/generator/serviceGenarator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ import {
// resolveFunctionName,
resolveRefs,
resolveTypeName,
// stripDot,
} from './util';

export default class ServiceGenerator {
Expand Down Expand Up @@ -865,6 +864,101 @@ export default class ServiceGenerator {
): boolean {
try {
const template = this.getTemplate(type);

// 应用 customRenderTemplateData hook (如果存在)
let processedParams = { ...params };
const customListHooks = this.config.hook?.customRenderTemplateData;

if (customListHooks && params.list) {
try {
const context = {
fileName,
params: processedParams,
};

let processedList = params.list;

// 根据不同的文件类型调用相应的 hook 函数
switch (type) {
case TypescriptFileType.serviceController:
if (customListHooks.serviceController) {
processedList = customListHooks.serviceController(
params.list as APIDataType[],
context
);
}
break;
case TypescriptFileType.reactQuery:
if (customListHooks.reactQuery) {
processedList = customListHooks.reactQuery(
params.list as APIDataType[],
context
);
}
break;
case TypescriptFileType.interface:
if (customListHooks.interface) {
processedList = customListHooks.interface(
params.list as ITypeItem[],
context
);
}
break;
case TypescriptFileType.displayEnumLabel:
if (customListHooks.displayEnumLabel) {
processedList = customListHooks.displayEnumLabel(
params.list as ITypeItem[],
context
);
}
break;
case TypescriptFileType.displayTypeLabel:
if (customListHooks.displayTypeLabel) {
processedList = customListHooks.displayTypeLabel(
params.list as ITypeItem[],
context
);
}
break;
case TypescriptFileType.schema:
if (customListHooks.schema) {
processedList = customListHooks.schema(
params.list as ISchemaItem[],
context
);
}
break;
case TypescriptFileType.serviceIndex:
if (customListHooks.serviceIndex) {
processedList = customListHooks.serviceIndex(
params.list as ControllerType[],
context
);
}
break;
}

if (processedList !== params.list) {
processedParams = {
...processedParams,
list: processedList,
};
this.log(
`customRenderTemplateData hook applied for ${type}: ${fileName}`
);
}
} catch (error) {
console.error(
`[GenSDK] customRenderTemplateData hook error for ${type}:`,
error
);
this.log(
`customRenderTemplateData hook failed for ${type}, using original list`
);
// 发生错误时使用原始参数继续执行
}
}

// 设置输出不转义
const env = nunjucks.configure({
autoescape: false,
Expand All @@ -874,7 +968,7 @@ export default class ServiceGenerator {
const destPath = join(this.config.serversPath, fileName);
const destCode = nunjucks.renderString(template, {
disableTypeCheck: false,
...params,
...processedParams,
});
let mergerProps: MergeOption = {} as MergeOption;

Expand Down
83 changes: 82 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import { PriorityRule, ReactQueryMode } from './config';
import type { TypescriptFileType } from './generator/config';
import { mockGenerator } from './generator/mockGenarator';
import ServiceGenerator from './generator/serviceGenarator';
import type { APIDataType, ITypeItem } from './generator/type';
import type {
APIDataType,
ControllerType,
ISchemaItem,
ITypeItem,
} from './generator/type';
import type {
ComponentsObject,
IPriorityRule,
Expand Down Expand Up @@ -265,6 +270,82 @@ export type GenerateServiceProps = {
config: U
) => ITypeItem[];
};
/**
* 自定义 genFileFromTemplate 的 list 参数 hook
* 可以在模板渲染前对 list 参数进行自定义处理
*/
customRenderTemplateData?: {
/**
* 自定义 serviceController 文件的 list 参数
*/
[TypescriptFileType.serviceController]?: (
list: APIDataType[],
context: {
fileName: string;
params: Record<string, unknown>;
}
) => APIDataType[];
/**
* 自定义 interface 文件的 list 参数
*/
[TypescriptFileType.interface]?: (
list: ITypeItem[],
context: {
fileName: string;
params: Record<string, unknown>;
}
) => ITypeItem[];
/**
* 自定义 displayEnumLabel 文件的 list 参数
*/
[TypescriptFileType.displayEnumLabel]?: (
list: ITypeItem[],
context: {
fileName: string;
params: Record<string, unknown>;
}
) => ITypeItem[];
/**
* 自定义 displayTypeLabel 文件的 list 参数
*/
[TypescriptFileType.displayTypeLabel]?: (
list: ITypeItem[],
context: {
fileName: string;
params: Record<string, unknown>;
}
) => ITypeItem[];
/**
* 自定义 schema 文件的 list 参数
*/
[TypescriptFileType.schema]?: (
list: ISchemaItem[],
context: {
fileName: string;
params: Record<string, unknown>;
}
) => ISchemaItem[];
/**
* 自定义 serviceIndex 文件的 list 参数
*/
[TypescriptFileType.serviceIndex]?: (
list: ControllerType[],
context: {
fileName: string;
params: Record<string, unknown>;
}
) => ControllerType[];
/**
* 自定义 reactQuery 文件的 list 参数
*/
[TypescriptFileType.reactQuery]?: (
list: APIDataType[],
context: {
fileName: string;
params: Record<string, unknown>;
}
) => APIDataType[];
};
};
};

Expand Down
Loading