Swagger2/OpenAPI3/Apifox to TypeScript/JavaScript, request client(support any client), request mock service, enum and enum translation, react-query/vue-query, type field label, JSON Schemas
npm install openapi-ts-request  !GitHub tag
English | 简体中文
根据 Swagger2/OpenAPI3/Apifox 文档生成:
- TypeScript/JavaScript
- 客户端请求函数(支持任意客户端)
- 模拟请求响应服务
- 枚举和枚举翻译
- react-query/vue-query
- 类型字段翻译
- JSON Schemas
- Apifox Config
文档:使用手册
- 支持 Swagger2.0/OpenAPI/Apifox 3.0,3.1 定义
- 生成 TypeScript/JavaScript, 请求客户端(支持任意客户端), 请求模拟服务, 枚举和枚举翻译, react-query/vue-query, 类型字段翻译, JSON Schemas
- 支持通过 npx、CLI、Nodejs 的方式使用
- 支持自定义请求工具函数, 支持 Fetch、Axios、UniApp-Request、Taro-Request、Node.js、XHR 客户端
- 支持通过 tags 过滤生成结果
- 支持 JSON/YAML 定义文件
- 支持将中文 tag 名称翻译为英文 tag 名称
- 支持直接配置apifox的token和projectId直接生成
``bashnpm
npm i openapi-ts-request --save-dev
$3
在项目根目录新建
openapi-ts-request.config.ts> 配置文件还支持 _.openapi-ts-request.ts_, _openapi-ts-request.config.cjs_ 等格式,参考 cosmiconfig
`ts
import { defineConfig } from 'openapi-ts-request';export default defineConfig({
schemaPath: 'http://petstore.swagger.io/v2/swagger.json',
serversPath: './src/apis',
});
`支持传入数组配置进行生成
`ts
import { defineConfig } from 'openapi-ts-request';export default defineConfig([
{
schemaPath: 'http://app.swagger.io/v2/swagger.json',
serversPath: './src/apis/app',
},
{
schemaPath: 'http://auth.swagger.io/v2/swagger.json',
serversPath: './src/apis/auth',
},
]);
`在
package.json 的 script 中添加命令: "openapi": "openapi-ts",运行:
`bash
npm run openapi
`生成的接口:
`bash
src/apis/index.ts #接口入口文件
src/apis/types.ts #类型定义文件
src/apis/pet.ts #接口文件
``typescript
// src/apis/pet.ts
/ eslint-disable /
// @ts-ignore
import request from 'axios';import * as API from './types';
/* Update an existing pet PUT /pet /
export async function updatePet({
body,
options,
}: {
body: API.Pet;
options?: { [key: string]: unknown };
}) {
return request(
/pet, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}// ... 其他接口
`$3
任意目录
xxx/xxx 新建 openapi-ts-request.config.js`ts
const { generateService } = require('openapi-ts-request');generateService({
schemaPath: 'http://petstore.swagger.io/v2/swagger.json',
serversPath: './apis',
});
`在
package.json 的 script 中添加命令: "openapi": "node xxx/xxx/openapi-ts-request.config.js"运行:
`bash
npm run openapi
`$3
任意目录
xxx/xxx 新建 openapi-ts-request.config.ts`ts
const { generateService } = require('openapi-ts-request');generateService({
schemaPath: 'http://petstore.swagger.io/v2/swagger.json',
serversPath: './apis',
});
`在
package.json 的 script 中添加命令: "openapi": "ts-node xxx/xxx/openapi-ts-request.config.ts",运行:
`bash
npm run openapi
`$3
`bash
npm
npx --package=openapi-ts-request -- openapi -i ./openapi.json -o ./apis
npx --package=openapi-ts-request -- openapi -i https://petstore3.swagger.io/api/v3/openapi.json -o ./apispnpm
pnpm --package=openapi-ts-request@latest dlx openapi -i ./openapi.json -o ./apis
pnpm --package=openapi-ts-request@latest dlx openapi -i https://petstore3.swagger.io/api/v3/openapi.json -o ./apis
`$3
`
npm i openapi-ts-request -g
``
$ openapi --help Usage: openapi [options]
Options:
-V, --version output the version number
-i, --input OpenAPI specification, can be a path, url
-o, --output output directory
-cfn, --configFileName config file name
-cfp, --configFilePath config file path
--requestLibPath custom request lib path, for example: "@/request", "node-fetch" (default: "axios")
--isSplitTypesByModule split types by module, generates {module}.type.ts, common.type.ts, enum.ts, types.ts (default: false)
-f, --full full replacement (default: true)
--enableLogging open the log (default: false)
--priorityRule priority rule, include/exclude/both (default: "include")
--filterCaseInsensitive whether to perform a case-insensitive match with includeTags, includePaths, excludeTags, excludePaths filters (default: false)
--includeTags <(string|RegExp)[]> generate code from include tags
--includePaths <(string|RegExp)[]> generate code from include paths
--excludeTags <(string|RegExp)[]> generate code from exclude tags
--excludePaths <(string|RegExp)[]> generate code from exclude paths
--requestOptionsType custom request method options parameter type (default: "{ [key: string]: unknown }")
--requestImportStatement custom request import statement, for example: "const request = require('@/request')"
--apiPrefix custom the prefix of the api path, for example: "api"(variable), "'api'"(string)
--isGenReactQuery generate react-query (default: false)
--reactQueryMode react-query mode, react/vue (default: "react")
--isGenJavaScript generate JavaScript (default: false)
--isDisplayTypeLabel generate label matching type field (default: false)
--isGenJsonSchemas generate JSON Schemas (default: false)
--mockFolder mock file path, for example: './mocks'
--authorization docs authorization
--nullable null instead of optional (default: false)
--isTranslateToEnglishTag translate chinese tag name to english tag name (default: false)
--isOnlyGenTypeScriptType only generate typescript type (default: false)
--isCamelCase camelCase naming of controller files and request client (default: true)
--isSupportParseEnumDesc parse enum description to generate enum label (default: false)
--supportParseEnumDescByReg custom regex for parsing enum description
-h, --help display help for command
`运行:
`bash
openapi --i ./spec.json --o ./apis
`参数
| 属性 | 必填 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| schemaPath | 否\* | string | - | Swagger2/OpenAPI3 地址(与 apifoxConfig 互斥,两者必填其一) |
| apifoxConfig | 否\* | Apifox Config | - | apifox 配置(与 schemaPath 互斥,两者必填其一) |
| serversPath | 否 | string | './src/apis' | 运行结果文件夹路径 |
| requestLibPath | 否 | string | 'axios' | 自定义请求方法路径,例如:'@/request'、'node-fetch' |
| isSplitTypesByModule | 否 | boolean | false | 按模块拆分类型文件,开启后会生成:{module}.type.ts(各模块类型)、common.type.ts(公共类型)、enum.ts(枚举类型)、types.ts(统一导出) |
| full | 否 | boolean | true | 是否全量替换 |
| describe | 否 | string | - | 描述信息,在用 cli 可交互运行方式时会用到 |
| enableLogging | 否 | boolean | false | 是否开启日志 |
| priorityRule | 否 | string | 'include' | 模式规则,可选include/exclude/both |
| filterCaseInsensitive | 否 | boolean | false | 执行 includeTags、includePaths、excludeTags、excludePaths 过滤时是否忽略大小写 |
| includeTags | 否 | (string\|RegExp)[] | - | 根据指定的 tags 生成代码, priorityRule=include则必填 |
| includePaths | 否 | (string\|RegExp)[] | - | 根据指定的 paths 生成代码 |
| excludeTags | 否 | (string\|RegExp)[] | - | 根据指定的 tags 不生成代码 |
| excludePaths | 否 | (string\|RegExp)[] | - | 根据指定的 paths 不生成代码 |
| requestOptionsType | 否 | string | '{ [key: string]: unknown }' | 自定义请求方法 options 参数类型 |
| requestImportStatement | 否 | string | - | 自定义请求方法表达式,例如:"const request = require('@/request')" |
| apiPrefix | 否 | string | - | api path的前缀,例如:'api'(动态变量), "'api'"(字符串) |
| isGenReactQuery | 否 | boolean | false | 是否生成 react-query |
| reactQueryMode | 否 | string | 'react' | react-query 模式,可选 react/vue |
| isGenJavaScript | 否 | boolean | false | 是否生成 JavaScript |
| isDisplayTypeLabel | 否 | boolean | false | 是否生成 type 对应的label |
| isGenJsonSchemas | 否 | boolean | false | 是否生成 JSON Schemas |
| mockFolder | 否 | string | - | mock文件路径,例如:'./mocks' |
| authorization | 否 | string | - | 文档权限凭证 |
| nullable | 否 | boolean | false | 使用 null 代替可选 |
| isTranslateToEnglishTag | 否 | boolean | false | 将中文 tag 名称翻译成英文 tag 名称 |
| isOnlyGenTypeScriptType | 否 | boolean | false | 仅生成 typescript 类型 |
| isCamelCase | 否 | boolean | true | 小驼峰命名文件和请求函数 |
| isSupportParseEnumDesc | 否 | boolean | false | 解析枚举描述生成枚举标签,格式参考:
系统用户角色:User(普通用户)=0,Agent(经纪人)=1,Admin(管理员)=2 |
| supportParseEnumDescByReg | 否 | string \| RegExp | - | 自定义正则表达式,用于解析 description 中的枚举定义。如果设置了此参数,将使用此正则表达式替代默认的 parseDescriptionEnum 方法。例如:/([^\s=<>/&;]+(?:\s+[^\s=<>/&;]+))\s=\s*(\d+)/g 可以匹配 "普通 = 0" 或 "SampleMaker = 1" 这样的格式 |
| binaryMediaTypes | 否 | string[] | - | 自定义二进制媒体类型列表,默认包含:['application/octet-stream', 'application/pdf', 'image/', 'video/', 'audio/*'] |
| hook | 否 | Custom Hook | - | 自定义 hook |自定义 Hook
| 属性 | 类型 | 说明 |
| --- | --- | --- |
| afterOpenApiDataInited | (openAPIData: OpenAPIObject) => OpenAPIObject | 自定义 OpenAPI 数据 |
| customFunctionName | (data: APIDataType) => string | 自定义请求方法函数名称 |
| customTypeName | (data: APIDataType) => string | 自定义类型名称 |
| customClassName | (tagName: string) => string | 自定义标签名 |
| customType | ({
schemaObject: SchemaObject \| ReferenceObject,
namespace: string,
originGetType:(schemaObject: SchemaObject \| ReferenceObject, namespace: string, schemas?: ComponentsObject['schemas']) => string,
schemas?: ComponentsObject['schemas'],
}) => string | 自定义类型
_返回非字符串将使用默认方法获取type_ |
| customFileNames | (
operationObject: OperationObject,
apiPath: string,
apiMethod: string,
) => string[] | 自定义生成的请求客户端文件名称,可以返回多个文件名称的数组(表示生成多个文件).
_返回为空,则使用默认的方法获取_ |
| customTemplates | {
[TypescriptFileType.serviceController]?: (item: T, context: U) => string;
} | 自定义模板,详情请看源码 |
| customRenderTemplateData | {
[TypescriptFileType]?: (list: any[], context: {fileName: string, params: Record}) => any[]
} | 自定义文件生成时的 list 参数处理,支持对不同文件类型进行精细化控制 |
Apifox-Config
| 属性 | 类型 | 说明 | 必填 |
| --- | --- | --- | --- |
| projectId | string | 项目id | true |
| apifoxToken | string | 获取 | true |
| local | string | 语言(默认: zh-CN) | false |
| apifoxVersion | string | 默认: 2024-03-28, 获取当前版本 | false |
| selectedTags | \ 或 string[] | 默认: \ | false |
| excludedByTags | string[] | 默认: [] | false |
| oasVersion | string | 指定用于导出的 OpenAPI 规范的版本,可以有值如 "2.0"、"3.0"、"3.1" | '3.0' |
| exportFormat | string | 指定导出的 OpenAPI 文件的格式,可以有值如 'JSON' 或 'YAML' | 'JSON' |
| includeApifoxExtensionProperties | boolean | 指定是否包含 Apifox 的 OpenAPI 规范扩展字段
x-apifox | false |
| addFoldersToTags | boolean | 指定是否在标签字段中包含接口的目录名称 | false |
| branchId | number | 分支ID | false |
| moduleId | number | 模块ID | false |JSON Schemas
- 默认生成 components.schemas 下面的 JSON Schemas,paths 对应的 JSON Schemas 目前需自行解析
- 提供一个解析 schema 的函数,用于将
$ref,$allOf 的引用填充到 当前schema`ts
export declare function patchSchema(
schema: ISchemaObject,
schemas: ComponentsObject['schemas']
): T;
`Mock
目前使用 mockjs 生成 mock 数据,mocks 文件启动需要借助 @umijs/server,后面会寻找其他方案以达到更好的 mock 体验
适配uniapp
适配 uniapp 推荐采用自定义 request 函数的方式,你也可以使用
@uni-helper/axios-adapter 适配器,详情见 【使用手册 2.2】旧版本升级注意事项
- 当前命名规范修改
- 当前版本已完成增量修改, 不会影响以前
- 可以弃用
openapi-ts命令, 直接使用openapi$3
`typescript
import type { APIDataType } from 'openapi-ts-request/dist/generator/type';
import {
genDefaultFunctionName,
resolveFunctionName,
stripDot,
} from 'openapi-ts-request/dist/generator/util';export default {
hook: {
customFunctionName(data: APIDataType, prefix: string) {
if (data.operationId)
return resolveFunctionName(stripDot(data.operationId), data.method);
return data.method + genDefaultFunctionName(data.path, prefix);
},
},
};
`贡献
$3
- node 18+
- pnpm 9+
$3
1. 熟悉 Pull Request 规范
2. fork 此仓库
3. 开一个新分支修改代码:
git checkout -b my-branch main
4. 确保你的代码可以通过所有测试用例(新增功能需要添加新的功能测试用例):pnpm test:unit
5. 创建 changeset 文件通过命令:pnpm changeset`