gen-api-types 1.0.13 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +32 -5
- package/README.md +30 -5
- package/docs/images/image.png +0 -0
- package/package.json +2 -1
- package/src/cli/index.ts +24 -17
package/README.en.md
CHANGED
|
@@ -10,8 +10,8 @@ With this tool, we can mark request interface classes and methods through TypeSc
|
|
|
10
10
|
|
|
11
11
|
> Note:
|
|
12
12
|
>
|
|
13
|
-
> 1. Because this tool uses TypeScript decorators, and decorators currently (TypeScript 5.0) do not support decorating plain functions directly, APIs must be written as **API classes +
|
|
14
|
-
> 2. This tool needs to dynamically execute TypeScript code (importing API classes and calling the marked
|
|
13
|
+
> 1. Because this tool uses TypeScript decorators, and decorators currently (TypeScript 5.0) do not support decorating plain functions directly, APIs must be written as **API classes + API methods**.
|
|
14
|
+
> 2. This tool needs to dynamically execute TypeScript code (importing API classes and calling the marked API methods), so it runs through the bundled `tsx` dependency. No global `tsx` installation is required.
|
|
15
15
|
|
|
16
16
|
#### Installation
|
|
17
17
|
|
|
@@ -90,13 +90,13 @@ Command output:
|
|
|
90
90
|
```shell
|
|
91
91
|
🚀 Start generating API types...
|
|
92
92
|
sourceFilesGlob [ 'src\\**\\*.ts' ]
|
|
93
|
-
📋 Processing
|
|
94
|
-
📋 Processing
|
|
93
|
+
📋 Processing TestApi.getList ...
|
|
94
|
+
📋 Processing TestApi.getWeather ...
|
|
95
95
|
Request results:
|
|
96
96
|
┌────────────────┬──────────────────────────────────────┐
|
|
97
97
|
│ (index) │ Values │
|
|
98
98
|
├────────────────┼──────────────────────────────────────┤
|
|
99
|
-
│ ✔️ successList │ '
|
|
99
|
+
│ ✔️ successList │ 'TestApi.getList TestApi.getWeather' │
|
|
100
100
|
│ ❌ errorList │ '' │
|
|
101
101
|
└────────────────┴──────────────────────────────────────┘
|
|
102
102
|
✅ API type generation completed
|
|
@@ -147,3 +147,30 @@ Generated output example:
|
|
|
147
147
|
export type XXX = { name: string };
|
|
148
148
|
export type Response_TestApi_getWeather = {...}
|
|
149
149
|
```
|
|
150
|
+
|
|
151
|
+
#### VS Code Extension
|
|
152
|
+
|
|
153
|
+
If you use `gen-api-types` in VS Code, you can install the companion extension [gen-api-types-vsce](https://github.com/xuejiangping/gen-api-types-vsce) to generate API return types from the context menu.
|
|
154
|
+
|
|
155
|
+

|
|
156
|
+
|
|
157
|
+
The extension does not bundle the CLI. It invokes the version of `gen-api-types` installed locally in the current project.
|
|
158
|
+
|
|
159
|
+
After installing the extension, right-click in a `.ts` or `.tsx` file containing the decorated APIs and select `Generate API Return Types (gen-api-types)`. By default, the extension will:
|
|
160
|
+
|
|
161
|
+
- Use the directory containing the current TypeScript file as the `api_dirs` argument
|
|
162
|
+
- Generate the type file in the same directory as the current TypeScript file
|
|
163
|
+
- Use `api-types.d.ts` as the default output file name
|
|
164
|
+
- Ask for confirmation before overwriting an existing output file
|
|
165
|
+
|
|
166
|
+
You can configure the CLI arguments in the VS Code settings:
|
|
167
|
+
|
|
168
|
+
| Extension setting | CLI argument | Default behavior |
|
|
169
|
+
| ---------------------------- | ---------------------- | ----------------------------------------------------- |
|
|
170
|
+
| `gen-api-types.projectRoot` | `-r, --project_root` | Workspace root containing the current TypeScript file |
|
|
171
|
+
| `gen-api-types.outputFile` | `-O, --output_file` | `api-types.d.ts` |
|
|
172
|
+
| `gen-api-types.outputDir` | `-o, --output_dir` | Directory containing the current TypeScript file |
|
|
173
|
+
| `gen-api-types.tsConfigPath` | `-t, --ts_config_path` | Not passed; the CLI uses its default value |
|
|
174
|
+
| `gen-api-types.isExported` | `--isExported` | `false` |
|
|
175
|
+
|
|
176
|
+
The extension is essentially a VS Code entry point for the CLI. Type analysis, API execution, and type-file generation are still handled by `gen-api-types`.
|
package/README.md
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
> 注意:
|
|
12
12
|
>
|
|
13
|
-
> 1. 由于需要使用到ts装饰器特性,而装饰器目前(ts 5.0)不支持直接标记普通函数,所以我们的接口必须以
|
|
14
|
-
> 2. 该工具需要动态执行 ts 代码(import
|
|
13
|
+
> 1. 由于需要使用到ts装饰器特性,而装饰器目前(ts 5.0)不支持直接标记普通函数,所以我们的接口必须以 **接口类+api方法** 的形式书写
|
|
14
|
+
> 2. 该工具需要动态执行 ts 代码(import接口类,然后调用标记的api方法),因此会通过内置依赖的 `tsx` 执行工具运行,无需额外全局安装 `tsx`。
|
|
15
15
|
|
|
16
16
|
#### 安装教程
|
|
17
17
|
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
|
|
20
20
|
```shell
|
|
21
21
|
npm install gen-api-types -D
|
|
22
|
-
|
|
23
22
|
```
|
|
24
23
|
|
|
25
24
|
#### 使用说明
|
|
@@ -49,8 +48,8 @@ export class TestApi {
|
|
|
49
48
|
|
|
50
49
|
- `@gen_type_c`装饰器函数,用来标记接口类。因为工具会动态分析指定目录下的所有 ts 文件,标记接口类,可以帮助我们快速定位接口类
|
|
51
50
|
- `@gen_type_m`装饰器函数标记需要转换的请求方法。它可以接收一个配置对象,包含两个字段。
|
|
52
|
-
1.
|
|
53
|
-
2.
|
|
51
|
+
1. `typeName: string` 接口返回类型名称,若不指定该字段,默认生成名称为: `Response_${类名}_${方法名}`
|
|
52
|
+
2. `args:any[] ` 方法参数列表,工具调用请求方法时,会将参数列表传入
|
|
54
53
|
|
|
55
54
|
> 注意:
|
|
56
55
|
|
|
@@ -148,3 +147,29 @@ npx gen-api-types --isExported -o output_dir -O output_file_name ./api_dir1 ./ap
|
|
|
148
147
|
export type XXX = { name: string };
|
|
149
148
|
export type Response_TestApi_getWeather = {...}
|
|
150
149
|
```
|
|
150
|
+
|
|
151
|
+
#### VS Code 插件
|
|
152
|
+
|
|
153
|
+
如果你在 VS Code 中使用 `gen-api-types` ,可以安装配套插件 [gen-api-types-vsce](https://github.com/xuejiangping/gen-api-types-vsce),通过右键菜单生成 API 返回类型。
|
|
154
|
+

|
|
155
|
+
|
|
156
|
+
插件不会内置 CLI,它会调用当前业务项目本地安装的 `gen-api-types`:
|
|
157
|
+
|
|
158
|
+
安装插件后,在已标记装饰器的 `.ts` / `.tsx` 文件中右键选择 `生成 API 返回类型(gen-api-types)` 即可。插件会默认:
|
|
159
|
+
|
|
160
|
+
- 将当前 TypeScript 文件所在目录作为 `api_dirs` 参数
|
|
161
|
+
- 将类型文件生成到当前 TypeScript 文件同目录
|
|
162
|
+
- 使用 `api-types.d.ts` 作为默认输出文件名
|
|
163
|
+
- 输出文件已存在时弹出覆盖确认
|
|
164
|
+
|
|
165
|
+
插件支持在 VS Code 设置中配置 CLI 参数:
|
|
166
|
+
|
|
167
|
+
| 插件配置项 | 对应 CLI 参数 | 默认行为 |
|
|
168
|
+
| ---------------------------- | ---------------------- | --------------------------------- |
|
|
169
|
+
| `gen-api-types.projectRoot` | `-r, --project_root` | 当前 TS 文件所在 workspace 根目录 |
|
|
170
|
+
| `gen-api-types.outputFile` | `-O, --output_file` | `api-types.d.ts` |
|
|
171
|
+
| `gen-api-types.outputDir` | `-o, --output_dir` | 当前 TS 文件所在目录 |
|
|
172
|
+
| `gen-api-types.tsConfigPath` | `-t, --ts_config_path` | 不传,由 CLI 使用默认值 |
|
|
173
|
+
| `gen-api-types.isExported` | `--isExported` | `false` |
|
|
174
|
+
|
|
175
|
+
插件本质上是对 CLI 的 VS Code 入口封装,类型分析、接口执行和类型文件生成仍由 `gen-api-types` 完成。
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gen-api-types",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.16",
|
|
4
4
|
"description": "一个自动生成请求接口返回类型的 cli 小工具",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"exports": {
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"files": [
|
|
31
31
|
"bin",
|
|
32
32
|
"src",
|
|
33
|
+
"docs",
|
|
33
34
|
"tsconfig.json",
|
|
34
35
|
"package.json"
|
|
35
36
|
],
|
package/src/cli/index.ts
CHANGED
|
@@ -26,6 +26,7 @@ type ApiMethodInfo = {
|
|
|
26
26
|
modulePath: string,
|
|
27
27
|
args: any[],
|
|
28
28
|
typeName: string,
|
|
29
|
+
isStatic: boolean
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
function parserDecoArgs(deco: Decorator): GenTypeOptions {
|
|
@@ -61,15 +62,14 @@ function getApiMethodsInfo() {
|
|
|
61
62
|
if (!c_deco) continue
|
|
62
63
|
const methods = classDeclaration.getMethods();
|
|
63
64
|
for (const method of methods) {
|
|
64
|
-
|
|
65
65
|
const className = classDeclaration.getName()!;
|
|
66
66
|
const methodName = method.getName();
|
|
67
67
|
const fullMethodName = `${className}.${methodName}`;
|
|
68
68
|
|
|
69
|
-
if (!method.isStatic()) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
69
|
+
// if (!method.isStatic()) {
|
|
70
|
+
// console.warn(`⚠️ ${fullMethodName} is not static method,only static method can be transformed`)
|
|
71
|
+
// continue
|
|
72
|
+
// }
|
|
73
73
|
// 4. 检查方法是否被我们的装饰器标记
|
|
74
74
|
const m_deco = method.getDecorator(M_DECO_NAME)
|
|
75
75
|
if (!m_deco) continue
|
|
@@ -77,7 +77,7 @@ function getApiMethodsInfo() {
|
|
|
77
77
|
const { args = [], typeName = `Response_${className}_${methodName}` } = parserDecoArgs(m_deco)
|
|
78
78
|
apiMethodsInfo.push({
|
|
79
79
|
className, methodName, fullMethodName, modulePath: sourceFile.getFilePath(),
|
|
80
|
-
typeName, args
|
|
80
|
+
typeName, args, isStatic: method.isStatic()
|
|
81
81
|
})
|
|
82
82
|
|
|
83
83
|
}
|
|
@@ -91,10 +91,13 @@ type ExecuteApiMethodResult = {
|
|
|
91
91
|
}
|
|
92
92
|
async function executeApiMethods(apiMethodsInfo: ApiMethodInfo[]): Promise<ExecuteApiMethodResult[]> {
|
|
93
93
|
const apiModuleMap = new Map<string, any>();
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
// debugger
|
|
95
|
+
const taskList: ExecuteApiMethodResult[] = []
|
|
96
|
+
for (const apiMethodInfo of apiMethodsInfo) {
|
|
97
|
+
const { className, methodName, fullMethodName, modulePath, args, typeName, isStatic } = apiMethodInfo
|
|
96
98
|
console.log(`📋 处理 ${fullMethodName} ...`);
|
|
97
99
|
let apiModule = null
|
|
100
|
+
// debugger
|
|
98
101
|
if (apiModuleMap.has(modulePath)) apiModule = apiModuleMap.get(modulePath)
|
|
99
102
|
else {
|
|
100
103
|
// apiModule = await import(modulePath)
|
|
@@ -108,31 +111,35 @@ async function executeApiMethods(apiMethodsInfo: ApiMethodInfo[]): Promise<Execu
|
|
|
108
111
|
if (apiModule) apiModuleMap.set(modulePath, apiModule)
|
|
109
112
|
} catch (error) {
|
|
110
113
|
console.log(`import ${modulePath} error \r\n`, error)
|
|
111
|
-
|
|
114
|
+
taskList.push({ error: `module error`, fullMethodName, typeName })
|
|
112
115
|
}
|
|
113
116
|
}
|
|
114
117
|
|
|
115
|
-
|
|
116
|
-
|
|
118
|
+
const apiMethod = isStatic ?
|
|
119
|
+
apiModule?.[className][methodName]
|
|
120
|
+
: apiModule?.[className].prototype[methodName]
|
|
117
121
|
if (apiMethod && typeof apiMethod === 'function') {
|
|
118
122
|
try {
|
|
119
123
|
// console.log(`🔍 Calling ${fullMethodName} with args:`, args);
|
|
120
124
|
const result = apiMethod.apply(apiModule, args)
|
|
121
125
|
const data = await Promise.resolve(result)
|
|
122
|
-
|
|
126
|
+
taskList.push({ data, typeName, fullMethodName })
|
|
123
127
|
} catch (error) {
|
|
124
128
|
console.error(`❌ ${fullMethodName} execute error:`, error)
|
|
125
|
-
|
|
129
|
+
taskList.push({ error, fullMethodName, typeName })
|
|
126
130
|
}
|
|
127
131
|
} else {
|
|
128
132
|
console.error(`❌ 无法获取 ${fullMethodName} 方法, 或不是可调用方法 `)
|
|
129
|
-
|
|
133
|
+
taskList.push({
|
|
130
134
|
error: `method error`, fullMethodName, typeName
|
|
131
|
-
}
|
|
135
|
+
})
|
|
132
136
|
}
|
|
133
|
-
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
134
141
|
|
|
135
|
-
return
|
|
142
|
+
return taskList
|
|
136
143
|
|
|
137
144
|
}
|
|
138
145
|
|