根据open api规范文档生成typescript接口文件
安装
npm install -g @lhy-meta-web/open-api
// 或者
yarn install -g @lhy-meta-web/open-api
// 或者
pnpm install -g @lhy-meta-web/open-api
使用
// typescript
import { GeneratorV2, GeneratorV3 } from '@lhy-meta-web/open-api'
// javascript
const { GeneratorV2, GeneratorV3 } = require('@lhy-meta-web/open-api')
const generator = new GeneratorV2({
api: 'open api v2的访问地址,可在swagger文档的http请求中找到',
template: {
outputDir: './dist-api',
clearOutputDir: true,
},
})
generator.build()
GeneratorConfig
属性 | 类型 | 描述 |
---|---|---|
api |
string | OpenAPI.Document | string[] | OpenAPI.Document[] |
swagger.json的url地址或json |
template |
TemplateConfig |
模板配置 |
commonUrl |
string |
公共的url前缀,生成器会自动计算一个最长公共子路径,commonUrl必须是最长公共子路径的子集。通常不需要使用该配置 |
formatter |
GeneratorFormatter |
格式化配置 |
package |
GeneratorPackage |
包路径配置 |
logger |
GeneratorLogger |
日志配置 |
GeneratorV2Config extends GeneratorConfig
属性 | 类型 | 描述 |
---|---|---|
makeEnum |
(...) => ResourceEnum |
生成枚举,可用于自定义枚举解析,具体定义详见dts |
makeEnumProperty |
(...) => ResourceEnumProperty |
生成枚举属性 |
TemplateConfig
模板配置
属性 | 类型 | 描述 |
---|---|---|
groupName |
string |
模板组名称,默认 default
|
outputDir |
string |
输出目录 |
outputFileName |
(filename: string) => string |
输出文件名,默认:${filename}.ts
|
outputFile |
(outputDir: string, packagePath: string, fileName: string) => string |
输出文件绝对路径,默认:path.resolve(outputDir, packagePath, fileName)
|
clearOutputDir |
boolean |
重新编译前清空输出目录 |
buildModelContext |
(model: ResourceModel, resource: Resource) => Record<string, unknown> |
生成Model编译上下文,可在模板中使用 |
buildEnumContext |
(enumModel: ResourceEnum, resource: Resource) => Record<string, unknown> |
生成Enum编译上下文,可在模板中使用 |
buildParameterModelContext |
(parameterModel: ResourceModel, resource: Resource) => Record<string, unknown> |
生成ParameterModel编译上下文,可在模板中使用 |
buildClassContext |
(clazz: ResourceClass, resource: Resource) => Record<string, unknown> |
生成Class编译上下文,可在模板中使用 |
GeneratorFormatter
包路径配置
属性 | 类型 | 描述 |
---|---|---|
className |
ResourceCodeNameFormatter |
类名,默认 pascal
|
classPropertyName |
ResourceCodeNameFormatter |
属性名,默认 hump
|
fileName |
ResourceFormatter |
文件名,默认 hyphen
|
export const ResourceFormatter = {
// 小驼峰
Hump: 'hump',
// 大驼峰
Pascal: 'pascal',
// 中划线
Hyphen: 'hyphen',
// 下划线
Snake: 'snake',
} as const
export type ResourceFormatter = ConstType<typeof ResourceFormatter>
export type ResourceCodeNameFormatter = Exclude<ResourceFormatter, typeof ResourceFormatter.Hyphen>
GeneratorPackage
包路径配置
属性 | 类型 | 描述 |
---|---|---|
model |
string |
Model包目录,默认 models
|
enum |
string |
Enum包目录,默认 enums
|
parameterModel |
string |
ParameterModel包目录,默认 parameter-models (取决于formatter.fileName) |
GeneratorLogger
日志配置
属性 | 类型 | 描述 |
---|---|---|
level |
LoggerLevel |
日志级别,默认warn
|
export const LoggerLevel = {
Info: 'info',
Warn: 'warn',
Error: 'error',
} as const
export type LoggerLevel = ConstType<typeof LoggerLevel>
- 从options.api读取Document json
- 将Document json转换为Resource(v2、v3差异在此)
- 根据配置从Template中获取模板组文件(可自定义扩展)
- 根据模板组文件读取对应的模板编译器(可自定义扩展)
- 根据配置项生成模板编译Context上下文(可配置扩展)
- 执行编译器并将编译后的文本写入文件
@lhy-meta-web/open-api会自动根据Document json中的所有url计算出最长公共子路径,并与commonUrl
做对比得出最终公共前缀,然后移除掉该公共路径后的下一级路径作为Class分类。
例:
- v1/api/user/save
- v1/api/user/update
- v1/api/role/update
- v1/api/menu/page
=> 最长公共子路径: v1/api/,得到Class分类
- user
- save
- update
- role
- update
- menu
- page
当配置commonUrl
时需要特别注意,commonUrl
下一级的接口会全部合并成一个Class类,可能存在同名方法的情况。
=> commonUrl = 'v1'
,得到的Class分类为
- api
- save => user.save
- update => user.update
- update => role.update,同名了
- page => menu.page
@lhy-meta-web/open-api采用nunjucks作为模板编译引擎,并内置了一套默认模板组,包含
- class.njk
- enum.njk
- model.njk
- TemplateFileType.Model (open api中定义好的模型)
- TemplateFileType.Enum (枚举,v2中的枚举是每个Model或ParameterModel的属性中独立生成,v3中可使用重用枚举)
- TemplateFileType.ParameterModel (针对Path、Query、FormData而新生成的参数模型)
- TemplateFileType.Class (用于多个Api static挂载的Class)
// 注册模板组
Template.registryGroup('自定义模板组名称', {
files: [
{
type: TemplateFileType.Model,
path: './default/model.njk',
},
{
type: TemplateFileType.Enum,
path: './default/enum.njk',
},
{
type: TemplateFileType.ParameterModel,
path: './default/model.njk',
},
{
type: TemplateFileType.Class,
path: './default/class.njk',
},
],
})
// 然后在配置中指定使用自己的模板组
const generator = new GeneratorV2({
api: 'open api v2的访问地址,可在swagger文档的http请求中找到',
template: {
groupName: '自定义模板组名称',
outputDir: './dist-api',
clearOutputDir: true,
},
})
模板编译器是针对模板文件类型的编译器
@lhy-meta-web/open-api内置了默认的模板编译器,可自定义覆盖默认编译器
import { Template } from '@lhy-meta-web/open-api'
import nunjucks from 'nunjucks'
Template.registryCompiler(
TemplateFileType.Model,
(templateContent: string, context: TemplateCompilerContext<typeof TemplateFileType.Model>, resource, config) => {
return nunjucks.renderString(templateContent, context)
}
)
import { TSTypeResolverV2 } from '@lhy-meta-web/open-api'
// 注意TSTypeResolverV2.mapping是只读属性
console.log(TSTypeResolverV2.mapping)
// 以下是默认值
// {
// object: 'Record<string, unknown>',
// string: 'string',
// integer: 'number',
// int: 'number',
// long: 'number',
// double: 'number',
// boolean: 'boolean',
// Map: 'Record',
// List: 'Array',
// Void: 'void',
// file: ' File',
// }
Object.assign(TSTypeResolverV2.mapping, {
// ...编写自己的类型映射
})
const generator = new GeneratorV2({
api: 'open api v2的访问地址,可在swagger文档的http请求中找到',
template: {
groupName: '自定义模板组名称',
outputDir: './dist-api',
outputFile(outputDir, packagePath, fileName) {
// 注意移除url中的前缀时要同时移除尾巴的/,否则生成地址时会放置到根目录
return path.resolve(__dirname, outputDir, packagePath.replace(/^api-prefix\/?/, ''), fileName)
},
},
})
- 接口文档中的泛型对象不能使用多泛型,只能是单泛型结构。如: User<Integer, String>是不允许的,User<Integer>是允许的
- 所有的泛型必须明确的指定类型,否则会被解析成unknown
- 应避免使用Object、JSON、Map等数据类型,尽可能使用明确的类型,此类均被解析成Record<string, unknown>
- 文件上传接口指定@ApiImplicitParams({@ApiImplicitParam(name = "file", dataType = "MultipartFile")}),在swagger文档上能显示 consumes ["multipart/form-data"]即可
- 返回文件流接口指定produces = MediaType.APPLICATION_OCTET_STREAM_VALUE,在swagger文档上能显示 produces ["application/octet-stream"]即可
- 目前不支持
allof
、oneof
、anyof
,泛型的判断依据于名称中包含/«.*»/
字符,主要适配于java的swagger生成
可发送邮件至邮箱810422646@qq.com
,标题请明确包含@lhy-meta-web/open-api
字样