npm package: @pnt-team/yapi-gen
Description: 根据 YApi 接口定义自动生成 TypeScript 类型声明和 API 函数
Latest version: 1.0.8

# @pnt-team/yapi-gen

根据 YApi 接口定义，自动生成 TypeScript 类型声明和 API 函数。

## 功能

- 从 API 文件中自动提取 `axios`/`fetch`/`instance` 调用的 URL，匹配 YApi 接口并生成 TypeScript 类型
- 自动给 API 调用补全参数类型和返回值类型
- 支持多项目配置，跨项目搜索接口
- 支持 `@yapi-project` 注释绑定文件到指定项目
- 支持 `--force` 强制更新已有类型（后端接口字段变更时使用）
- 支持 `--project` 指定项目搜索
- 支持单文件、批量、按 URL 三种运行模式
- 自动去重嵌套子类型，避免同名 interface 冲突

## 安装

```bash
# 全局安装
npm install -g @pnt-team/yapi-gen

# 或作为项目开发依赖
npm install -D @pnt-team/yapi-gen
```

## 配置

在项目根目录创建 `yapi-config.json`（可参考 `yapi-config.example.json`）：

```json
{
  "yapiBaseUrl": "https://your-yapi-domain.com",
  "outputDir": "src/api",
  "projects": [
    {
      "name": "项目名称",
      "token": "your-yapi-project-token"
    },
    {
      "name": "另一个项目",
      "token": "another-project-token"
    }
  ]
}
```

| 字段 | 说明 |
|------|------|
| `yapiBaseUrl` | YApi 服务地址 |
| `outputDir` | 类型文件输出目录，类型会写入 `{outputDir}/types/{module}.ts` |
| `projects` | YApi 项目列表，每个项目需要 `name` 和 `token` |

> **token 获取方式**：进入 YApi 项目 → 设置 → token 配置 → 复制 token

### 兼容旧格式

也支持单项目的简写格式：

```json
{
  "yapiBaseUrl": "https://your-yapi-domain.com",
  "outputDir": "src/api",
  "token": "your-yapi-project-token"
}
```

## 使用

### 模式一：按文件生成（推荐）

扫描指定 API 文件中的 `axios`/`fetch`/`instance` 调用，自动匹配 YApi 接口并生成类型：

```bash
yapi-gen --file src/api/account.ts
# 简写
yapi-gen -f src/api/account.ts
```

**效果：**
1. 提取文件中所有 `axios.get('/xxx')`、`fetch('/xxx')`、`instance.post('/xxx')` 等调用的 URL
2. 在配置的所有 YApi 项目中搜索匹配的接口
3. 生成类型文件到 `src/api/types/account.ts`
4. 自动更新源文件：给 API 调用补上参数类型和返回值类型

### 模式二：批量生成

自动扫描 `src/api/` 目录下所有 `.ts` 文件并批量处理：

```bash
yapi-gen --all
# 简写
yapi-gen -a
```

### 模式三：按接口 URL 生成

指定 YApi 接口路径，生成类型并追加 API 函数到对应模块文件：

```bash
yapi-gen --url /sacc/find --module account
# 简写
yapi-gen -u /sacc/find -m account
```

**效果：**
1. 在 YApi 中搜索路径为 `/sacc/find` 的接口
2. 生成类型到 `src/api/types/account.ts`
3. 在 `src/api/account.ts` 中追加对应的 API 函数

### 强制更新已有类型

当后端在 YApi 上修改了接口字段（改名、加字段、删字段、改类型），默认情况下脚本会跳过已存在的类型。使用 `--force` 可以强制覆盖更新：

```bash
# 更新单个文件的类型
yapi-gen -f src/api/translate.ts --force

# 批量更新所有文件
yapi-gen --all --force

# 按 URL 模式也支持
yapi-gen --url /api/user/info --module user --force
```

| 场景 | 不加 `--force` | 加 `--force` |
|------|---------------|-------------|
| 类型名已存在 | ⏭️ 跳过，不写入 | ✅ 替换为最新定义 |
| 新类型 | ✅ 追加 | ✅ 追加 |
| 类型文件不存在 | ✅ 新建 | ✅ 新建 |

### 绑定文件到指定项目（@yapi-project）

如果你的项目配置了多个 YApi 项目，可以在 API 文件顶部添加注释，限定该文件只在指定项目中搜索接口，避免跨项目匹配到错误的同名接口：

```typescript
// @yapi-project 用户服务

import axios from 'axios';

export const getUser = (params) =>
  axios.get('/api/user/info', { params });
```

这样运行 `yapi-gen -f src/api/user.ts` 时，只会在名为 `用户服务` 的项目中搜索接口。

### 指定项目搜索（--project）

在 `--url` 模式下，可以用 `--project` 参数指定只在某个项目中搜索：

```bash
yapi-gen --url /api/user/info --module user --project 用户服务
# 简写
yapi-gen -u /api/user/info -m user -p 用户服务
```

### 指定配置文件

默认读取项目根目录的 `yapi-config.json`，也可以手动指定：

```bash
yapi-gen -f src/api/account.ts --config ./config/yapi.json
# 简写
yapi-gen -f src/api/account.ts -c ./config/yapi.json
```

### 查看帮助

```bash
yapi-gen --help
```

## 生成示例

假设 `src/api/account.ts` 中有：

```typescript
export const getAccountInfo = (params) =>
  axios.get('/api/account/info', { params });

export const getUserList = (data) =>
  instance.post('/api/user/list', data);
```

运行 `yapi-gen -f src/api/account.ts` 后：

**生成类型文件** `src/api/types/account.ts`：

```typescript
/**
 * 本文件由 yapi-gen 自动生成，请勿手动修改
 */

export type AccountInfoQuery = {
  id: number;
};

export interface AccountInfoResponse {
  name: string;
  email?: string;
  avatar?: string;
}

export interface UserListBody {
  page: number;
  pageSize: number;
}

export interface UserListResponse {
  total: number;
  list: UserListResponseListItem[];
}

interface UserListResponseListItem {
  id: number;
  name: string;
}
```

**自动更新源文件** `src/api/account.ts`：

```typescript
import { AccountInfoQuery, AccountInfoResponse, UserListBody, UserListResponse } from './types/account';

export const getAccountInfo = (params: AccountInfoQuery): Promise<commonEesType<AccountInfoResponse>> =>
  axios.get('/api/account/info', { params });

export const getUserList = (data: UserListBody): Promise<commonEesType<UserListResponse>> =>
  instance.post('/api/user/list', data);
```

> 支持 `axios`、`fetch`、`instance` 以及自定义实例的 `.get`/`.post`/`.put`/`.delete`/`.patch` 调用。

## 输出结构

```
src/api/
├── account.ts          ← API 函数文件（自动补全类型）
├── user.ts
└── types/
    ├── account.ts      ← 自动生成的类型声明
    └── user.ts
```

## 作为 Library 使用

除了 CLI，也可以在代码中导入核心函数：

```typescript
import { findApisInYapi, processApi, schemaToTs } from '@pnt-team/yapi-gen';
```

## CLI 参数一览

| 参数 | 简写 | 类型 | 说明 |
|------|------|------|------|
| `--file` | `-f` | string | 指定 API 文件路径 |
| `--all` | `-a` | boolean | 批量处理 src/api 下所有文件 |
| `--url` | `-u` | string | 指定 YApi 接口路径 |
| `--module` | `-m` | string | 指定模块名（配合 --url） |
| `--project` | `-p` | string | 指定 YApi 项目名称，只在该项目中搜索 |
| `--force` | - | boolean | 强制更新已有类型定义（默认 false） |
| `--config` | `-c` | string | 配置文件路径（默认 yapi-config.json） |
| `--help` | `-h` | - | 查看帮助 |
| `--version` | `-v` | - | 查看版本号 |

## 注意事项

- 配置文件 `yapi-config.json` 包含 token 敏感信息，**不要提交到 Git 仓库**
- 类型文件由工具自动生成，请勿手动修改（再次运行会被覆盖）
- URL 匹配时会自动忽略 `/api/v1/`、`/api/v2/` 等前缀
- 已使用 axios 泛型（如 `axios.post<A, B, C>(...)`）的调用不会被自动替换
- 多项目配置时，建议使用 `@yapi-project` 注释绑定文件到指定项目，避免跨项目误匹配
- 后端修改了接口字段后，使用 `--force` 参数来同步更新本地类型定义
- 支持 `axios`、`fetch`、`instance` 等调用方式的 URL 提取

## License

MIT