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 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 + static API methods**.
14
- > 2. This tool needs to dynamically execute TypeScript code (importing API classes and calling the marked static API methods), so it runs through the bundled `tsx` dependency. No global `tsx` installation is required.
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 UserApi.getList ...
94
- 📋 Processing UserApi.getWeather ...
93
+ 📋 Processing TestApi.getList ...
94
+ 📋 Processing TestApi.getWeather ...
95
95
  Request results:
96
96
  ┌────────────────┬──────────────────────────────────────┐
97
97
  │ (index) │ Values │
98
98
  ├────────────────┼──────────────────────────────────────┤
99
- │ ✔️ successList │ 'UserApi.getList UserApi.getWeather' │
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
+ ![alt text](docs/images/image.png)
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)不支持直接标记普通函数,所以我们的接口必须以 **接口类+静态api方法** 的形式书写
14
- > 2. 该工具需要动态执行 ts 代码(import接口类,然后调用标记的静态api方法),因此会通过内置依赖的 `tsx` 执行工具运行,无需额外全局安装 `tsx`。
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. `typeName: string` 接口返回类型名称,若不指定该字段,默认生成名称为: `Response_${类名}_${方法名}`
53
- 2. `args:any[] ` 方法参数列表,工具调用请求方法时,会将参数列表传入
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
+ ![alt text](docs/images/image.png)
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.13",
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
- console.warn(`⚠️ ${fullMethodName} is not static method,only static method can be transformed`)
71
- continue
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
- const taskList = apiMethodsInfo.map(async (apiMethodInfo) => {
95
- const { className, methodName, fullMethodName, modulePath, args, typeName } = apiMethodInfo
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
- return { error: `module error`, fullMethodName, typeName }
114
+ taskList.push({ error: `module error`, fullMethodName, typeName })
112
115
  }
113
116
  }
114
117
 
115
-
116
- const apiMethod = apiModule?.[className]?.[methodName]
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
- return { data, typeName, fullMethodName }
126
+ taskList.push({ data, typeName, fullMethodName })
123
127
  } catch (error) {
124
128
  console.error(`❌ ${fullMethodName} execute error:`, error)
125
- return { error, fullMethodName, typeName }
129
+ taskList.push({ error, fullMethodName, typeName })
126
130
  }
127
131
  } else {
128
132
  console.error(`❌ 无法获取 ${fullMethodName} 方法, 或不是可调用方法 `)
129
- return {
133
+ taskList.push({
130
134
  error: `method error`, fullMethodName, typeName
131
- }
135
+ })
132
136
  }
133
- })
137
+ }
138
+
139
+
140
+
134
141
 
135
- return Promise.all(taskList)
142
+ return taskList
136
143
 
137
144
  }
138
145