文档与类型导出
在实际项目中,服务端与客户端往往由不同团队并行开发。如果客户端能直接获取服务端的接口类型定义与 API 文档,将显著提升协作效率、减少联调成本。
sora 框架内置了 export:api 与 export:doc 两条命令,分别用于导出 TypeScript 类型声明和 OpenAPI 3.0 文档,一条命令即可完成。
类型导出
npx sora export:api执行后输出:
Scanning source files...
Collecting export targets...
Found 2 routes, 0 entities, 4 simple exports
Export complete!类型声明文件默认生成在 dist-api/api.ts(由 sora.json 中的 apiDeclarationOutput 字段决定),内容示例:
// Auto-generated by sora export:api
export interface AuthHandler {
test(body: void): Promise<{ test: boolean; }>;
}
export interface BusinessHandler {
ping(body: IPingRequest): Promise<IPingResponse>;
}
export enum UserErrorCode {
ErrUnknown = 'ERR_UNKNOWN'
}
export interface IPingRequest {
message?: string;
}
export interface IPingResponse {
message: string;
timestamp: number;
}客户端或其他工程可直接引用该文件,获得完整的类型提示与编译期校验。
文档生成
npx sora export:docOpenAPI 3.0 文档默认生成在 dist-api/doc.yml(由 sora.json 中的 docOutput 字段决定),可直接导入 Swagger UI、Apifox 等工具进行接口浏览与调试。
控制导出内容
sora 通过 JSDoc 注解控制声明级别的导出行为。下表为注解总览:
| 注解 | 作用位置 | 影响命令 |
|---|---|---|
@soraExport | 类、枚举、接口、类型别名 | export:api、export:doc |
@soraTargets | 类、枚举、接口、类型别名 | export:api、export:doc |
@soraIgnore | 方法、属性 | export:api、export:doc |
@soraPrefix | 类(仅 route) | export:doc |
@method | 方法 | export:doc |
@description | 方法 | export:doc |
此外,以下框架装饰器也参与导出控制:
| 装饰器 | 来源 | 影响命令 |
|---|---|---|
@Route.method | @sora-soft/framework | export:api、export:doc |
@Route.notify | @sora-soft/framework | export:api、export:doc |
@soraExport
标记声明需要被导出处理。未添加此注解的声明将被完全忽略。
用于 Route 类 — export:api 将其转为接口(保留 @Route.method 方法的参数与返回类型),export:doc 为每个方法生成 OpenAPI PathItem:
/**
* @soraExport route
* @soraPrefix /auth
*/
class AuthHandler extends Route {
@Route.method
async login(@guard body: IReqLogin): Promise<IRespLogin> { ... }
}export:api 输出:
export interface AuthHandler {
login(body: IReqLogin): Promise<IRespLogin>;
}用于 数据类 — export:api 将其转为接口,仅保留公共非静态属性:
/**
* @soraExport
*/
class UserEntity {
public id: string;
public name: string;
private internalState: any;
}export:api 输出:
export interface UserEntity {
id: string;
name: string;
}用于枚举、interface、type — 直接原样导出:
/** @soraExport */
enum UserRole {
Admin = "admin",
User = "user",
}
/** @soraExport */
interface IApiResponse<T> {
code: number;
data: T;
}@soraTargets
按目标环境过滤导出内容。配合 --target 参数使用:只有 @soraTargets 匹配的声明(以及未指定 @soraTargets 的声明)会被导出。
/**
* @soraExport route
* @soraTargets web
*/
class WebHandler extends Route { ... }
/**
* @soraExport route
* @soraTargets admin
*/
class AdminHandler extends Route { ... }
/**
* @soraExport route
*/
class CommonHandler extends Route { ... }# 仅导出 web 目标:输出 WebHandler + CommonHandler,AdminHandler 被过滤
npx sora export:api --target web
# 不指定 target:全部导出
npx sora export:api@soraPrefix
为 Route 类中的方法指定 URL 路径前缀,影响 export:doc 生成的 OpenAPI 路径。默认值为 /,支持逗号分隔多个前缀。
/**
* @soraExport route
* @soraPrefix /api/v1/auth
*/
class AuthHandler extends Route {
@Route.method
async login() { ... }
}export:doc 生成的路径为 /api/v1/auth/login。
@soraIgnore
从导出中排除指定成员。不传参数时在所有 target 下忽略;传入 target 名称时仅在对应 target 下忽略。
/**
* @soraExport route
*/
class AuthHandler extends Route {
@Route.method
async login() { ... }
/**
* @soraIgnore
*/
@Route.method
async internalDebug() { ... }
/**
* @soraIgnore admin
*/
@Route.method
async verifyToken() { ... }
}internalDebug:所有 target 下均被忽略verifyToken:仅在admintarget 下被忽略
@method
指定 HTTP 方法,用于 export:doc 生成 OpenAPI 文档。可选值:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS,默认为 POST。
/**
* @soraExport route
*/
class UserHandler extends Route {
/**
* 获取用户信息
* @method GET
*/
@Route.method
async getUser() { ... }
}@description
为方法添加详细描述,映射到 OpenAPI operation 的 description 字段。JSDoc 注释的首行文本映射为 summary,@description 映射为 description。
/**
* @soraExport route
*/
class AuthHandler extends Route {
/**
* 用户登录 ← 映射为 summary
* @description 使用用户名和密码进行身份验证,返回 JWT token。
* 支持邮箱和手机号登录。 ← 映射为 description
*/
@Route.method
async login() { ... }
}export:doc 输出:
/login:
post:
summary: 用户登录
description: 使用用户名和密码进行身份验证,返回 JWT token。支持邮箱和手机号登录。@Route.method 与 @Route.notify
这两个是框架装饰器(非 JSDoc 注解),但直接影响导出行为:
@Route.method— 请求-响应模式。export:api保留方法签名,export:doc生成对应文档。@Route.notify— 单向通知模式。export:api同样保留方法签名,export:doc不生成文档条目。