Skip to content

文档与类型导出

在实际项目中,服务端与客户端往往由不同团队并行开发。如果客户端能直接获取服务端的接口类型定义与 API 文档,将显著提升协作效率、减少联调成本。

sora 框架内置了 export:apiexport:doc 两条命令,分别用于导出 TypeScript 类型声明和 OpenAPI 3.0 文档,一条命令即可完成。

类型导出

bash
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 字段决定),内容示例:

typescript
// 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;
}

客户端或其他工程可直接引用该文件,获得完整的类型提示与编译期校验。

文档生成

bash
npx sora export:doc

OpenAPI 3.0 文档默认生成在 dist-api/doc.yml(由 sora.json 中的 docOutput 字段决定),可直接导入 Swagger UI、Apifox 等工具进行接口浏览与调试。

控制导出内容

sora 通过 JSDoc 注解控制声明级别的导出行为。下表为注解总览:

注解作用位置影响命令
@soraExport类、枚举、接口、类型别名export:apiexport:doc
@soraTargets类、枚举、接口、类型别名export:apiexport:doc
@soraIgnore方法、属性export:apiexport:doc
@soraPrefix类(仅 route)export:doc
@method方法export:doc
@description方法export:doc

此外,以下框架装饰器也参与导出控制:

装饰器来源影响命令
@Route.method@sora-soft/frameworkexport:apiexport:doc
@Route.notify@sora-soft/frameworkexport:apiexport:doc

@soraExport

标记声明需要被导出处理。未添加此注解的声明将被完全忽略。

用于 Route 类export:api 将其转为接口(保留 @Route.method 方法的参数与返回类型),export:doc 为每个方法生成 OpenAPI PathItem:

typescript
/**
 * @soraExport route
 * @soraPrefix /auth
 */
class AuthHandler extends Route {
  @Route.method
  async login(@guard body: IReqLogin): Promise<IRespLogin> { ... }
}

export:api 输出:

typescript
export interface AuthHandler {
  login(body: IReqLogin): Promise<IRespLogin>;
}

用于 数据类export:api 将其转为接口,仅保留公共非静态属性:

typescript
/**
 * @soraExport
 */
class UserEntity {
  public id: string;
  public name: string;
  private internalState: any;
}

export:api 输出:

typescript
export interface UserEntity {
  id: string;
  name: string;
}

用于枚举、interface、type — 直接原样导出:

typescript
/** @soraExport */
enum UserRole {
  Admin = "admin",
  User = "user",
}

/** @soraExport */
interface IApiResponse<T> {
  code: number;
  data: T;
}

@soraTargets

按目标环境过滤导出内容。配合 --target 参数使用:只有 @soraTargets 匹配的声明(以及未指定 @soraTargets 的声明)会被导出。

typescript
/**
 * @soraExport route
 * @soraTargets web
 */
class WebHandler extends Route { ... }

/**
 * @soraExport route
 * @soraTargets admin
 */
class AdminHandler extends Route { ... }

/**
 * @soraExport route
 */
class CommonHandler extends Route { ... }
bash
# 仅导出 web 目标:输出 WebHandler + CommonHandler,AdminHandler 被过滤
npx sora export:api --target web

# 不指定 target:全部导出
npx sora export:api

@soraPrefix

为 Route 类中的方法指定 URL 路径前缀,影响 export:doc 生成的 OpenAPI 路径。默认值为 /,支持逗号分隔多个前缀。

typescript
/**
 * @soraExport route
 * @soraPrefix /api/v1/auth
 */
class AuthHandler extends Route {
  @Route.method
  async login() { ... }
}

export:doc 生成的路径为 /api/v1/auth/login

@soraIgnore

从导出中排除指定成员。不传参数时在所有 target 下忽略;传入 target 名称时仅在对应 target 下忽略。

typescript
/**
 * @soraExport route
 */
class AuthHandler extends Route {
  @Route.method
  async login() { ... }

  /**
   * @soraIgnore
   */
  @Route.method
  async internalDebug() { ... }

  /**
   * @soraIgnore admin
   */
  @Route.method
  async verifyToken() { ... }
}
  • internalDebug:所有 target 下均被忽略
  • verifyToken:仅在 admin target 下被忽略

@method

指定 HTTP 方法,用于 export:doc 生成 OpenAPI 文档。可选值:GETPOSTPUTDELETEPATCHHEADOPTIONS,默认为 POST

typescript
/**
 * @soraExport route
 */
class UserHandler extends Route {
  /**
   * 获取用户信息
   * @method GET
   */
  @Route.method
  async getUser() { ... }
}

@description

为方法添加详细描述,映射到 OpenAPI operation 的 description 字段。JSDoc 注释的首行文本映射为 summary@description 映射为 description

typescript
/**
 * @soraExport route
 */
class AuthHandler extends Route {
  /**
   * 用户登录                          ← 映射为 summary
   * @description 使用用户名和密码进行身份验证,返回 JWT token。
   *              支持邮箱和手机号登录。   ← 映射为 description
   */
  @Route.method
  async login() { ... }
}

export:doc 输出:

yaml
/login:
  post:
    summary: 用户登录
    description: 使用用户名和密码进行身份验证,返回 JWT token。支持邮箱和手机号登录。

@Route.method@Route.notify

这两个是框架装饰器(非 JSDoc 注解),但直接影响导出行为:

  • @Route.method — 请求-响应模式。export:api 保留方法签名,export:doc 生成对应文档。
  • @Route.notify — 单向通知模式。export:api 同样保留方法签名,export:doc 不生成文档条目。

基于 WTFPL 许可发布