swagger2api-v3 1.0.9 → 1.1.0
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.md +233 -198
- package/dist/cli/index.js +44 -40
- package/dist/core/generator.js +80 -40
- package/dist/index.js +10 -3
- package/dist/types/index.d.ts +3 -1
- package/package.json +68 -68
- package/dist/utils/request.d.ts +0 -17
- package/dist/utils/request.js +0 -49
package/README.md
CHANGED
|
@@ -1,199 +1,234 @@
|
|
|
1
|
-
# Swagger2API-v3
|
|
2
|
-
|
|
3
|
-
English | [中文](./README_CN.md)
|
|
4
|
-
|
|
5
|
-
A powerful command-line tool for automatically generating TypeScript interface code from Swagger (OAS3.0) documentation.
|
|
6
|
-
|
|
7
|
-
## ✨ Features
|
|
8
|
-
|
|
9
|
-
- 🚀 **Fast Generation** - Quickly generate TypeScript interface code from Swagger JSON
|
|
10
|
-
- 📁 **Smart Grouping** - Support automatic file grouping by Swagger tags
|
|
11
|
-
- 📝 **Detailed Comments** - Automatically generate detailed comments including descriptions, parameters, and return values
|
|
12
|
-
- 🎨 **Code Formatting** - Support custom formatting commands
|
|
13
|
-
- ⚙️ **Environment Adaptation** - Automatically detect project environment and generate corresponding configuration files
|
|
14
|
-
- 🔧 **CLI Tool** - Provide complete command-line tools
|
|
15
|
-
|
|
16
|
-
## 📦 Installation
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
# Global installation
|
|
20
|
-
npm install -g swagger2api-v3
|
|
21
|
-
|
|
22
|
-
# Project dependency
|
|
23
|
-
npm install swagger2api-v3
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## 🚀 Quick Start
|
|
27
|
-
|
|
28
|
-
### 1. Initialize Configuration File
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
npx swagger2api-v3 init
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### 2. Configuration File Description
|
|
35
|
-
|
|
36
|
-
The tool automatically generates configuration files in the corresponding format based on the project environment:
|
|
37
|
-
|
|
38
|
-
**CommonJS Environment** (`"type": "commonjs"` or not set):
|
|
39
|
-
```javascript
|
|
40
|
-
const config = {
|
|
41
|
-
input: 'https://petstore.swagger.io/v2/swagger.json',
|
|
42
|
-
output: './src/api',
|
|
43
|
-
importTemplate: "import { request } from '@/utils/request';",
|
|
44
|
-
generator: 'typescript',
|
|
45
|
-
groupByTags: true,
|
|
46
|
-
overwrite: true,
|
|
47
|
-
prefix: '',
|
|
48
|
-
lint: 'prettier --write',
|
|
49
|
-
options: {
|
|
50
|
-
addComments: true
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
module.exports = config;
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
**ES Module Environment** (`"type": "module"`):
|
|
58
|
-
```javascript
|
|
59
|
-
const config = {
|
|
60
|
-
// ... same configuration
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
export default config;
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### 3. Generate Interface Code
|
|
67
|
-
|
|
68
|
-
```bash
|
|
69
|
-
npx swagger2api-v3 generate
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
## ⚙️ Configuration Options
|
|
73
|
-
|
|
74
|
-
| Option | Type | Default | Description |
|
|
75
|
-
|--------|------|---------|-------------|
|
|
76
|
-
| `input` | string | - | Swagger JSON file path or URL |
|
|
77
|
-
| `output` | string | `'./src/api'` | Output directory for generated code |
|
|
78
|
-
| `generator` | string | `'typescript'` | Code generator type |
|
|
79
|
-
| `groupByTags` | boolean | `true` | Whether to group files by tags |
|
|
80
|
-
| `overwrite` | boolean | `true` | Whether to overwrite existing files |
|
|
81
|
-
| `prefix` | string | `''` | Common prefix for API paths |
|
|
82
|
-
| `importTemplate` | string | - | Import statement template for request function |
|
|
83
|
-
| `
|
|
84
|
-
| `
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
├──
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
└── index.ts
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
*/
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
1
|
+
# Swagger2API-v3
|
|
2
|
+
|
|
3
|
+
English | [中文](./README_CN.md)
|
|
4
|
+
|
|
5
|
+
A powerful command-line tool for automatically generating TypeScript interface code from Swagger (OAS3.0) documentation.
|
|
6
|
+
|
|
7
|
+
## ✨ Features
|
|
8
|
+
|
|
9
|
+
- 🚀 **Fast Generation** - Quickly generate TypeScript interface code from Swagger JSON
|
|
10
|
+
- 📁 **Smart Grouping** - Support automatic file grouping by Swagger tags
|
|
11
|
+
- 📝 **Detailed Comments** - Automatically generate detailed comments including descriptions, parameters, and return values
|
|
12
|
+
- 🎨 **Code Formatting** - Support custom formatting commands
|
|
13
|
+
- ⚙️ **Environment Adaptation** - Automatically detect project environment and generate corresponding configuration files
|
|
14
|
+
- 🔧 **CLI Tool** - Provide complete command-line tools
|
|
15
|
+
|
|
16
|
+
## 📦 Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Global installation
|
|
20
|
+
npm install -g swagger2api-v3
|
|
21
|
+
|
|
22
|
+
# Project dependency
|
|
23
|
+
npm install swagger2api-v3
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 🚀 Quick Start
|
|
27
|
+
|
|
28
|
+
### 1. Initialize Configuration File
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx swagger2api-v3 init
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 2. Configuration File Description
|
|
35
|
+
|
|
36
|
+
The tool automatically generates configuration files in the corresponding format based on the project environment:
|
|
37
|
+
|
|
38
|
+
**CommonJS Environment** (`"type": "commonjs"` or not set):
|
|
39
|
+
```javascript
|
|
40
|
+
const config = {
|
|
41
|
+
input: 'https://petstore.swagger.io/v2/swagger.json',
|
|
42
|
+
output: './src/api',
|
|
43
|
+
importTemplate: "import { request } from '@/utils/request';",
|
|
44
|
+
generator: 'typescript',
|
|
45
|
+
groupByTags: true,
|
|
46
|
+
overwrite: true,
|
|
47
|
+
prefix: '',
|
|
48
|
+
lint: 'prettier --write',
|
|
49
|
+
options: {
|
|
50
|
+
addComments: true
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
module.exports = config;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**ES Module Environment** (`"type": "module"`):
|
|
58
|
+
```javascript
|
|
59
|
+
const config = {
|
|
60
|
+
// ... same configuration
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export default config;
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 3. Generate Interface Code
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npx swagger2api-v3 generate
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## ⚙️ Configuration Options
|
|
73
|
+
|
|
74
|
+
| Option | Type | Default | Description |
|
|
75
|
+
|--------|------|---------|-------------|
|
|
76
|
+
| `input` | string | - | Swagger JSON file path or URL |
|
|
77
|
+
| `output` | string | `'./src/api'` | Output directory for generated code |
|
|
78
|
+
| `generator` | string | `'typescript'` | Code generator type. Supports `'typescript'` and `'javascript'`. `'javascript'` outputs `.js` files and skips type file generation |
|
|
79
|
+
| `groupByTags` | boolean | `true` | Whether to group files by tags |
|
|
80
|
+
| `overwrite` | boolean | `true` | Whether to overwrite existing files |
|
|
81
|
+
| `prefix` | string | `''` | Common prefix for API paths |
|
|
82
|
+
| `importTemplate` | string | - | Import statement template for request function |
|
|
83
|
+
| `requestStyle` | 'method' \| 'generic' | `'generic'` | Request call style: `method` uses `request.get/post`, `generic` uses `request({ method })` |
|
|
84
|
+
| `lint` | string | - | Code formatting command (optional) |
|
|
85
|
+
| `options.addComments` | boolean | `true` | Whether to add detailed comments |
|
|
86
|
+
|
|
87
|
+
## 📁 Generated File Structure
|
|
88
|
+
|
|
89
|
+
### Grouped by Tags (Recommended)
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
src/api/
|
|
93
|
+
├── types.ts # Data type definitions (TypeScript mode only)
|
|
94
|
+
├── user/ # User-related APIs
|
|
95
|
+
│ └── index.ts
|
|
96
|
+
├── auth/ # Auth-related APIs
|
|
97
|
+
│ └── index.ts
|
|
98
|
+
└── index.ts # Entry file
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### JavaScript Output
|
|
102
|
+
|
|
103
|
+
When `generator: 'javascript'` is set:
|
|
104
|
+
|
|
105
|
+
- Outputs `.js` files (`index.js`, `api.js`, `user/index.js`, etc.)
|
|
106
|
+
- Does not generate a `types.ts` file
|
|
107
|
+
- Removes TypeScript-specific syntax (types, `import type`, generics like `<T>`)
|
|
108
|
+
|
|
109
|
+
Example generated API function (method style):
|
|
110
|
+
|
|
111
|
+
```javascript
|
|
112
|
+
export const codeAuth = (data, config) => {
|
|
113
|
+
return request.post({ url: '/api/auth/codeAuth', data, ...config });
|
|
114
|
+
};
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Example generated API function (generic style):
|
|
118
|
+
|
|
119
|
+
```javascript
|
|
120
|
+
export const codeAuth = (data, config) => {
|
|
121
|
+
return request({ url: '/api/auth/codeAuth', method: 'POST', data, ...config });
|
|
122
|
+
};
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Not Grouped
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
src/api/
|
|
129
|
+
├── types.ts # Data type definitions
|
|
130
|
+
├── api.ts # All API interfaces
|
|
131
|
+
└── index.ts # Entry file
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## 💡 Usage Examples
|
|
135
|
+
|
|
136
|
+
### Generated Type Definitions
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
// types.ts
|
|
140
|
+
export interface LoginDto {
|
|
141
|
+
/** Account */
|
|
142
|
+
account: string;
|
|
143
|
+
/** Password */
|
|
144
|
+
password: string;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export interface UserInfo {
|
|
148
|
+
/** User ID */
|
|
149
|
+
id: string;
|
|
150
|
+
/** Username */
|
|
151
|
+
username: string;
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Generated API Interfaces
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
// authController/index.ts
|
|
159
|
+
import { request } from '@/utils/request';
|
|
160
|
+
import type { LoginDto, LoginRespDto } from '../types';
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Login
|
|
164
|
+
* @param data Login parameters
|
|
165
|
+
* @param config Optional request configuration
|
|
166
|
+
*/
|
|
167
|
+
export const authControllerLoginPost = (data: LoginDto, config?: any) => {
|
|
168
|
+
return request.post<LoginRespDto>({
|
|
169
|
+
url: '/admin/auth/login',
|
|
170
|
+
data,
|
|
171
|
+
...config
|
|
172
|
+
});
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// When requestStyle is set to 'generic':
|
|
176
|
+
export const authControllerLoginPost2 = (data: LoginDto, config?: any) => {
|
|
177
|
+
return request<LoginRespDto>({
|
|
178
|
+
url: '/admin/auth/login',
|
|
179
|
+
data,
|
|
180
|
+
method: 'POST',
|
|
181
|
+
...config
|
|
182
|
+
});
|
|
183
|
+
};
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## 🔧 CLI Commands
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
# Initialize configuration file
|
|
190
|
+
npx swagger2api-v3 init [--force]
|
|
191
|
+
|
|
192
|
+
# Generate interface code
|
|
193
|
+
npx swagger2api-v3 generate [--config <path>]
|
|
194
|
+
|
|
195
|
+
# Validate configuration file
|
|
196
|
+
npx swagger2api-v3 validate [--config <path>]
|
|
197
|
+
|
|
198
|
+
# Show help
|
|
199
|
+
npx swagger2api-v3 --help
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## 📝 NPM Scripts
|
|
203
|
+
|
|
204
|
+
Add to `package.json`:
|
|
205
|
+
|
|
206
|
+
```json
|
|
207
|
+
{
|
|
208
|
+
"scripts": {
|
|
209
|
+
"api:generate": "swagger2api-v3 generate",
|
|
210
|
+
"api:init": "swagger2api-v3 init",
|
|
211
|
+
"api:validate": "swagger2api-v3 validate"
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## 🎨 Code Formatting
|
|
217
|
+
|
|
218
|
+
Support automatic execution of formatting commands after generation:
|
|
219
|
+
|
|
220
|
+
```javascript
|
|
221
|
+
// In configuration file
|
|
222
|
+
const config = {
|
|
223
|
+
// ... other configurations
|
|
224
|
+
lint: 'prettier --write' // or 'eslint --fix', etc.
|
|
225
|
+
};
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## 🤝 Contributing
|
|
229
|
+
|
|
230
|
+
Issues and Pull Requests are welcome!
|
|
231
|
+
|
|
232
|
+
## 📄 License
|
|
233
|
+
|
|
199
234
|
MIT License
|
package/dist/cli/index.js
CHANGED
|
@@ -98,54 +98,58 @@ program
|
|
|
98
98
|
process.exit(1);
|
|
99
99
|
}
|
|
100
100
|
// 检测当前项目的模块类型
|
|
101
|
-
let isESModule =
|
|
101
|
+
let isESModule = true; // 默认使用 ES Module
|
|
102
102
|
const packageJsonPath = path.resolve(process.cwd(), 'package.json');
|
|
103
103
|
if (fs.existsSync(packageJsonPath)) {
|
|
104
104
|
try {
|
|
105
105
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
106
|
-
|
|
106
|
+
// 只有明确设置为 commonjs 时才使用 CommonJS,否则默认使用 ES Module
|
|
107
|
+
isESModule = packageJson.type !== 'commonjs';
|
|
107
108
|
}
|
|
108
109
|
catch (error) {
|
|
109
|
-
console.warn('⚠️ 无法读取package.json,使用默认
|
|
110
|
+
console.warn('⚠️ 无法读取package.json,使用默认ES Module格式');
|
|
110
111
|
}
|
|
111
112
|
}
|
|
112
|
-
const configContent = `/**
|
|
113
|
-
* Swagger2API 配置文件
|
|
114
|
-
* 用于配置从 Swagger JSON 生成前端接口的参数
|
|
115
|
-
*/
|
|
116
|
-
const config = {
|
|
117
|
-
// Swagger JSON 文件路径或 URL
|
|
118
|
-
input: 'http://localhost:3000/admin/docs/json',
|
|
119
|
-
|
|
120
|
-
// 输出目录
|
|
121
|
-
output: './src/api',
|
|
122
|
-
|
|
123
|
-
// request 导入路径模板
|
|
124
|
-
importTemplate: "import { request } from '@/utils/request';",
|
|
125
|
-
|
|
126
|
-
// 生成器类型
|
|
127
|
-
generator: 'typescript',
|
|
128
|
-
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
//
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
//
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
//
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
//
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
113
|
+
const configContent = `/**
|
|
114
|
+
* Swagger2API 配置文件
|
|
115
|
+
* 用于配置从 Swagger JSON 生成前端接口的参数
|
|
116
|
+
*/
|
|
117
|
+
const config = {
|
|
118
|
+
// Swagger JSON 文件路径或 URL
|
|
119
|
+
input: 'http://localhost:3000/admin/docs/json',
|
|
120
|
+
|
|
121
|
+
// 输出目录
|
|
122
|
+
output: './src/api',
|
|
123
|
+
|
|
124
|
+
// request 导入路径模板
|
|
125
|
+
importTemplate: "import { request } from '@/utils/request';",
|
|
126
|
+
|
|
127
|
+
// 生成器类型
|
|
128
|
+
generator: 'typescript', // 可选 'javascript'(JS 模式输出 .js 文件且不生成类型文件)
|
|
129
|
+
|
|
130
|
+
// 请求调用风格:'method' 使用 request.get/post;'generic' 使用 request({ method })
|
|
131
|
+
requestStyle: 'generic',
|
|
132
|
+
|
|
133
|
+
// 按标签分组生成文件
|
|
134
|
+
groupByTags: true,
|
|
135
|
+
|
|
136
|
+
// 是否覆盖更新,默认为true。为true时会先删除输出目录下的所有文件
|
|
137
|
+
overwrite: true,
|
|
138
|
+
|
|
139
|
+
// 接口路径公共前缀,默认为空字符串
|
|
140
|
+
prefix: '',
|
|
141
|
+
|
|
142
|
+
// 代码格式化命令(可选)
|
|
143
|
+
lint: 'prettier --write',
|
|
144
|
+
|
|
145
|
+
// 生成选项
|
|
146
|
+
options: {
|
|
147
|
+
// 是否添加注释
|
|
148
|
+
addComments: true
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
${isESModule ? 'export default config;' : 'module.exports = config;'}
|
|
149
153
|
`;
|
|
150
154
|
try {
|
|
151
155
|
fs.writeFileSync(configPath, configContent, 'utf-8');
|
package/dist/core/generator.js
CHANGED
|
@@ -57,8 +57,9 @@ class CodeGenerator {
|
|
|
57
57
|
}
|
|
58
58
|
// 确保输出目录存在
|
|
59
59
|
(0, utils_1.ensureDirectoryExists)(this.config.output);
|
|
60
|
-
//
|
|
61
|
-
if (this.config.
|
|
60
|
+
// 生成类型文件(仅在 TypeScript 模式下生成)
|
|
61
|
+
if (this.config.generator === 'typescript' &&
|
|
62
|
+
this.config.options?.generateModels !== false) {
|
|
62
63
|
await this.generateTypesFile(types);
|
|
63
64
|
}
|
|
64
65
|
// 生成API文件
|
|
@@ -97,7 +98,7 @@ class CodeGenerator {
|
|
|
97
98
|
const header = [
|
|
98
99
|
'/**',
|
|
99
100
|
' * API 类型定义',
|
|
100
|
-
' * 此文件由 swagger2api 自动生成,请勿手动修改',
|
|
101
|
+
' * 此文件由 swagger2api-v3 自动生成,请勿手动修改',
|
|
101
102
|
' */',
|
|
102
103
|
''
|
|
103
104
|
].join('\n');
|
|
@@ -130,7 +131,8 @@ class CodeGenerator {
|
|
|
130
131
|
const tagFolderPath = path.join(this.config.output, folderName);
|
|
131
132
|
// 确保tag文件夹存在
|
|
132
133
|
(0, utils_1.ensureDirectoryExists)(tagFolderPath);
|
|
133
|
-
const
|
|
134
|
+
const ext = this.config.generator === 'javascript' ? 'js' : 'ts';
|
|
135
|
+
const filePath = path.join(tagFolderPath, `index.${ext}`);
|
|
134
136
|
const content = this.generateApiFileContent(apis, types, tag);
|
|
135
137
|
(0, utils_1.writeFile)(filePath, content);
|
|
136
138
|
}
|
|
@@ -141,7 +143,8 @@ class CodeGenerator {
|
|
|
141
143
|
* @param types 类型定义数组
|
|
142
144
|
*/
|
|
143
145
|
async generateSingleApiFile(apis, types) {
|
|
144
|
-
const
|
|
146
|
+
const ext = this.config.generator === 'javascript' ? 'js' : 'ts';
|
|
147
|
+
const filePath = path.join(this.config.output, `api.${ext}`);
|
|
145
148
|
const content = this.generateApiFileContent(apis, types);
|
|
146
149
|
(0, utils_1.writeFile)(filePath, content);
|
|
147
150
|
}
|
|
@@ -157,15 +160,17 @@ class CodeGenerator {
|
|
|
157
160
|
const header = [
|
|
158
161
|
'/**',
|
|
159
162
|
` * ${tag ? `${tag} ` : ''}API 接口`,
|
|
160
|
-
' * 此文件由 swagger2api 自动生成,请勿手动修改',
|
|
163
|
+
' * 此文件由 swagger2api-v3 自动生成,请勿手动修改',
|
|
161
164
|
' */',
|
|
162
165
|
'',
|
|
163
166
|
importTemplate + ';'
|
|
164
167
|
];
|
|
165
168
|
// 收集当前文件实际使用的类型
|
|
166
169
|
const usedTypes = this.collectUsedTypes(apis);
|
|
167
|
-
//
|
|
168
|
-
if (
|
|
170
|
+
// 添加类型导入(仅在 TypeScript 且生成类型文件时)
|
|
171
|
+
if (this.config.generator === 'typescript' &&
|
|
172
|
+
this.config.options?.generateModels !== false &&
|
|
173
|
+
usedTypes.length > 0) {
|
|
169
174
|
const typeNames = usedTypes.join(', ');
|
|
170
175
|
const typesPath = tag ? '../types' : './types';
|
|
171
176
|
header.push(`import type { ${typeNames} } from '${typesPath}';`);
|
|
@@ -204,13 +209,25 @@ class CodeGenerator {
|
|
|
204
209
|
schema: p.schema || { type: p.type }
|
|
205
210
|
}));
|
|
206
211
|
// 生成直接参数形式
|
|
207
|
-
const functionParams = this.generateDirectParameters(swaggerParameters);
|
|
212
|
+
const functionParams = this.generateDirectParameters(swaggerParameters, this.config.generator === 'javascript');
|
|
208
213
|
const responseType = api.responseType || 'any';
|
|
209
214
|
const functionName = (0, utils_1.toCamelCase)(api.name);
|
|
210
215
|
parts.push(`export const ${functionName} = (${functionParams}) => {`);
|
|
211
216
|
// 生成请求配置
|
|
212
|
-
const
|
|
213
|
-
|
|
217
|
+
const useGenericRequest = this.config.requestStyle === 'generic';
|
|
218
|
+
const requestConfig = this.generateRequestConfig(api, useGenericRequest);
|
|
219
|
+
const isJS = this.config.generator === 'javascript';
|
|
220
|
+
if (useGenericRequest) {
|
|
221
|
+
parts.push(isJS
|
|
222
|
+
? ` return request(${requestConfig});`
|
|
223
|
+
: ` return request<${responseType}>(${requestConfig});`);
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
const method = api.method.toLowerCase();
|
|
227
|
+
parts.push(isJS
|
|
228
|
+
? ` return request.${method}(${requestConfig});`
|
|
229
|
+
: ` return request.${method}<${responseType}>(${requestConfig});`);
|
|
230
|
+
}
|
|
214
231
|
parts.push('}');
|
|
215
232
|
return parts.join('\n');
|
|
216
233
|
}
|
|
@@ -219,7 +236,7 @@ class CodeGenerator {
|
|
|
219
236
|
* @param parameters Swagger参数数组
|
|
220
237
|
* @returns 函数参数字符串
|
|
221
238
|
*/
|
|
222
|
-
generateDirectParameters(parameters) {
|
|
239
|
+
generateDirectParameters(parameters, isJavaScript = false) {
|
|
223
240
|
const params = [];
|
|
224
241
|
const queryParams = parameters.filter((p) => p.in === 'query');
|
|
225
242
|
const pathParams = parameters.filter((p) => p.in === 'path');
|
|
@@ -228,37 +245,52 @@ class CodeGenerator {
|
|
|
228
245
|
// 合并路径参数和查询参数为一个params对象
|
|
229
246
|
const allParams = [...pathParams, ...queryParams];
|
|
230
247
|
if (allParams.length > 0) {
|
|
231
|
-
|
|
232
|
-
.
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
248
|
+
if (isJavaScript) {
|
|
249
|
+
params.push('params');
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
const paramType = allParams
|
|
253
|
+
.map((p) => {
|
|
254
|
+
const optional = p.required ? '' : '?';
|
|
255
|
+
return `${p.name}${optional}: ${p.type}`;
|
|
256
|
+
})
|
|
257
|
+
.join(', ');
|
|
258
|
+
// 检查是否所有参数都是可选的
|
|
259
|
+
const allOptional = allParams.every((p) => !p.required);
|
|
260
|
+
const optionalModifier = allOptional ? '?' : '';
|
|
261
|
+
params.push(`params${optionalModifier}: { ${paramType} }`);
|
|
262
|
+
}
|
|
241
263
|
}
|
|
242
264
|
// 请求体参数
|
|
243
265
|
if (bodyParams.length > 0) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
266
|
+
if (isJavaScript) {
|
|
267
|
+
params.push('data');
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
const bodyParam = bodyParams[0];
|
|
271
|
+
const bodyType = bodyParam.schema
|
|
272
|
+
? this.getTypeFromSchema(bodyParam.schema)
|
|
273
|
+
: bodyParam.type;
|
|
274
|
+
params.push(`data: ${bodyType}`);
|
|
275
|
+
}
|
|
249
276
|
}
|
|
250
277
|
// 表单参数
|
|
251
278
|
if (formParams.length > 0) {
|
|
252
|
-
|
|
253
|
-
.
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
279
|
+
if (isJavaScript) {
|
|
280
|
+
params.push('data');
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
const formType = formParams
|
|
284
|
+
.map((p) => {
|
|
285
|
+
const optional = p.required ? '' : '?';
|
|
286
|
+
return `${p.name}${optional}: ${p.type}`;
|
|
287
|
+
})
|
|
288
|
+
.join(', ');
|
|
289
|
+
params.push(`data: { ${formType} }`);
|
|
290
|
+
}
|
|
259
291
|
}
|
|
260
292
|
// 添加可选的config参数
|
|
261
|
-
params.push('config?: any');
|
|
293
|
+
params.push(isJavaScript ? 'config' : 'config?: any');
|
|
262
294
|
return params.join(', ');
|
|
263
295
|
}
|
|
264
296
|
/**
|
|
@@ -363,7 +395,7 @@ class CodeGenerator {
|
|
|
363
395
|
* @param api API接口信息
|
|
364
396
|
* @returns 请求配置代码
|
|
365
397
|
*/
|
|
366
|
-
generateRequestConfig(api) {
|
|
398
|
+
generateRequestConfig(api, includeMethod = false) {
|
|
367
399
|
const config = [];
|
|
368
400
|
// URL处理
|
|
369
401
|
let url = api.path;
|
|
@@ -397,6 +429,10 @@ class CodeGenerator {
|
|
|
397
429
|
else if (formParams.length > 0) {
|
|
398
430
|
config.push('data');
|
|
399
431
|
}
|
|
432
|
+
// 在通用请求风格下添加 method 字段
|
|
433
|
+
if (includeMethod) {
|
|
434
|
+
config.push(`method: '${api.method}'`);
|
|
435
|
+
}
|
|
400
436
|
// 添加config参数合并
|
|
401
437
|
config.push('...config');
|
|
402
438
|
return `{\n ${config.join(',\n ')}\n }`;
|
|
@@ -407,8 +443,11 @@ class CodeGenerator {
|
|
|
407
443
|
*/
|
|
408
444
|
async generateIndexFile(groupedApis) {
|
|
409
445
|
const exports = [];
|
|
410
|
-
//
|
|
411
|
-
|
|
446
|
+
// 导出类型(仅在 TypeScript 且生成类型文件时)
|
|
447
|
+
if (this.config.generator === 'typescript' &&
|
|
448
|
+
this.config.options?.generateModels !== false) {
|
|
449
|
+
exports.push("export * from './types';");
|
|
450
|
+
}
|
|
412
451
|
if (this.config.groupByTags) {
|
|
413
452
|
// 按标签导出
|
|
414
453
|
for (const tag of groupedApis.keys()) {
|
|
@@ -423,13 +462,14 @@ class CodeGenerator {
|
|
|
423
462
|
const content = [
|
|
424
463
|
'/**',
|
|
425
464
|
' * API 入口文件',
|
|
426
|
-
' * 此文件由 swagger2api 自动生成,请勿手动修改',
|
|
465
|
+
' * 此文件由 swagger2api-v3 自动生成,请勿手动修改',
|
|
427
466
|
' */',
|
|
428
467
|
'',
|
|
429
468
|
...exports,
|
|
430
469
|
''
|
|
431
470
|
].join('\n');
|
|
432
|
-
const
|
|
471
|
+
const ext = this.config.generator === 'javascript' ? 'js' : 'ts';
|
|
472
|
+
const filePath = path.join(this.config.output, `index.${ext}`);
|
|
433
473
|
(0, utils_1.writeFile)(filePath, content);
|
|
434
474
|
}
|
|
435
475
|
/**
|
package/dist/index.js
CHANGED
|
@@ -48,7 +48,12 @@ const utils_1 = require("./utils");
|
|
|
48
48
|
*/
|
|
49
49
|
class Swagger2API {
|
|
50
50
|
constructor(config) {
|
|
51
|
-
|
|
51
|
+
// 规范化配置:设置默认值
|
|
52
|
+
this.config = {
|
|
53
|
+
...config,
|
|
54
|
+
// 默认请求风格为 generic
|
|
55
|
+
requestStyle: config.requestStyle ?? 'generic'
|
|
56
|
+
};
|
|
52
57
|
}
|
|
53
58
|
/**
|
|
54
59
|
* 生成API接口文件
|
|
@@ -95,8 +100,10 @@ class Swagger2API {
|
|
|
95
100
|
if (!this.config.output) {
|
|
96
101
|
errors.push('output 配置项不能为空');
|
|
97
102
|
}
|
|
98
|
-
|
|
99
|
-
|
|
103
|
+
// 支持 typescript 与 javascript 两种生成器
|
|
104
|
+
if (this.config.generator !== 'typescript' &&
|
|
105
|
+
this.config.generator !== 'javascript') {
|
|
106
|
+
errors.push('目前只支持 typescript 或 javascript 生成器');
|
|
100
107
|
}
|
|
101
108
|
if (errors.length > 0) {
|
|
102
109
|
console.error('❌ 配置验证失败:');
|
package/dist/types/index.d.ts
CHANGED
|
@@ -10,13 +10,15 @@ export interface SwaggerConfig {
|
|
|
10
10
|
/** 输出目录 */
|
|
11
11
|
output: string;
|
|
12
12
|
/** 生成器类型 */
|
|
13
|
-
generator: 'typescript';
|
|
13
|
+
generator: 'typescript' | 'javascript';
|
|
14
14
|
/** 按 tags 分组生成文件 */
|
|
15
15
|
groupByTags: boolean;
|
|
16
16
|
/** 是否覆盖更新,默认为true。为true时会先删除输出目录下的所有文件 */
|
|
17
17
|
overwrite?: boolean;
|
|
18
18
|
/** 接口路径公共前缀,默认为空字符串 */
|
|
19
19
|
prefix?: string;
|
|
20
|
+
/** 请求调用风格:'method' 使用 request.get/post;'generic' 使用 request({ method }) */
|
|
21
|
+
requestStyle?: 'method' | 'generic';
|
|
20
22
|
/** 标签分组配置 */
|
|
21
23
|
tagGrouping?: TagGroupingConfig;
|
|
22
24
|
/** 生成选项 */
|
package/package.json
CHANGED
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "swagger2api-v3",
|
|
3
|
-
"version": "1.0
|
|
4
|
-
"description": "
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
7
|
-
"type": "commonjs",
|
|
8
|
-
"bin": {
|
|
9
|
-
"swagger2api-v3": "dist/cli/index.js"
|
|
10
|
-
},
|
|
11
|
-
"files": [
|
|
12
|
-
"dist",
|
|
13
|
-
"README.md",
|
|
14
|
-
"package.json"
|
|
15
|
-
],
|
|
16
|
-
"scripts": {
|
|
17
|
-
"test": "jest",
|
|
18
|
-
"test:watch": "jest --watch",
|
|
19
|
-
"test:coverage": "jest --coverage",
|
|
20
|
-
"test:ci": "jest --ci --coverage --watchAll=false",
|
|
21
|
-
"build": "tsc",
|
|
22
|
-
"clean": "rimraf dist",
|
|
23
|
-
"prebuild": "npm run clean",
|
|
24
|
-
"start": "node dist/cli/index.js",
|
|
25
|
-
"dev": "npm run build && npm start",
|
|
26
|
-
"lint": "prettier --write",
|
|
27
|
-
"generate": "npm run build && node dist/cli/index.js generate",
|
|
28
|
-
"init": "npm run build && node dist/cli/index.js init",
|
|
29
|
-
"validate": "npm run build && node dist/cli/index.js validate",
|
|
30
|
-
"swagger:generate": "npm run generate",
|
|
31
|
-
"swagger:run": "npm run generate",
|
|
32
|
-
"swagger:init": "npm run init",
|
|
33
|
-
"swagger:validate": "npm run validate"
|
|
34
|
-
},
|
|
35
|
-
"keywords": [
|
|
36
|
-
"swagger",
|
|
37
|
-
"openapi",
|
|
38
|
-
"typescript",
|
|
39
|
-
"api",
|
|
40
|
-
"generator",
|
|
41
|
-
"cli",
|
|
42
|
-
"code-generation"
|
|
43
|
-
],
|
|
44
|
-
"author": "xiaoyang",
|
|
45
|
-
"license": "MIT",
|
|
46
|
-
"homepage": "https://github.com/xiaoyang33/swagger2api-v3#readme",
|
|
47
|
-
"repository": {
|
|
48
|
-
"type": "git",
|
|
49
|
-
"url": "https://github.com/xiaoyang33/swagger2api-v3.git"
|
|
50
|
-
},
|
|
51
|
-
"bugs": {
|
|
52
|
-
"url": "https://github.com/xiaoyang33/swagger2api-v3/issues"
|
|
53
|
-
},
|
|
54
|
-
"packageManager": "pnpm@10.11.0",
|
|
55
|
-
"devDependencies": {
|
|
56
|
-
"@types/jest": "^29.5.0",
|
|
57
|
-
"@types/node": "^24.3.1",
|
|
58
|
-
"jest": "^29.5.0",
|
|
59
|
-
"prettier": "^3.6.2",
|
|
60
|
-
"rimraf": "^6.0.1",
|
|
61
|
-
"ts-jest": "^29.1.0",
|
|
62
|
-
"typescript": "^5.9.2"
|
|
63
|
-
},
|
|
64
|
-
"dependencies": {
|
|
65
|
-
"axios": "^1.11.0",
|
|
66
|
-
"commander": "^12.0.0"
|
|
67
|
-
}
|
|
68
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "swagger2api-v3",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "A command-line tool for generating TypeScript API interfaces from Swagger (OAS 3.0) documentation",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"type": "commonjs",
|
|
8
|
+
"bin": {
|
|
9
|
+
"swagger2api-v3": "dist/cli/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"README.md",
|
|
14
|
+
"package.json"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"test": "jest",
|
|
18
|
+
"test:watch": "jest --watch",
|
|
19
|
+
"test:coverage": "jest --coverage",
|
|
20
|
+
"test:ci": "jest --ci --coverage --watchAll=false",
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"clean": "rimraf dist",
|
|
23
|
+
"prebuild": "npm run clean",
|
|
24
|
+
"start": "node dist/cli/index.js",
|
|
25
|
+
"dev": "npm run build && npm start",
|
|
26
|
+
"lint": "prettier --write",
|
|
27
|
+
"generate": "npm run build && node dist/cli/index.js generate",
|
|
28
|
+
"init": "npm run build && node dist/cli/index.js init",
|
|
29
|
+
"validate": "npm run build && node dist/cli/index.js validate",
|
|
30
|
+
"swagger:generate": "npm run generate",
|
|
31
|
+
"swagger:run": "npm run generate",
|
|
32
|
+
"swagger:init": "npm run init",
|
|
33
|
+
"swagger:validate": "npm run validate"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"swagger",
|
|
37
|
+
"openapi",
|
|
38
|
+
"typescript",
|
|
39
|
+
"api",
|
|
40
|
+
"generator",
|
|
41
|
+
"cli",
|
|
42
|
+
"code-generation"
|
|
43
|
+
],
|
|
44
|
+
"author": "xiaoyang",
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"homepage": "https://github.com/xiaoyang33/swagger2api-v3#readme",
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "https://github.com/xiaoyang33/swagger2api-v3.git"
|
|
50
|
+
},
|
|
51
|
+
"bugs": {
|
|
52
|
+
"url": "https://github.com/xiaoyang33/swagger2api-v3/issues"
|
|
53
|
+
},
|
|
54
|
+
"packageManager": "pnpm@10.11.0",
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/jest": "^29.5.0",
|
|
57
|
+
"@types/node": "^24.3.1",
|
|
58
|
+
"jest": "^29.5.0",
|
|
59
|
+
"prettier": "^3.6.2",
|
|
60
|
+
"rimraf": "^6.0.1",
|
|
61
|
+
"ts-jest": "^29.1.0",
|
|
62
|
+
"typescript": "^5.9.2"
|
|
63
|
+
},
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"axios": "^1.11.0",
|
|
66
|
+
"commander": "^12.0.0"
|
|
67
|
+
}
|
|
68
|
+
}
|
package/dist/utils/request.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { type AxiosRequestConfig, type AxiosResponse, type CreateAxiosDefaults, type InternalAxiosRequestConfig } from 'axios';
|
|
2
|
-
export interface IReqBoay<T> {
|
|
3
|
-
code: number;
|
|
4
|
-
data: T;
|
|
5
|
-
message: string;
|
|
6
|
-
}
|
|
7
|
-
declare class HttpRequest {
|
|
8
|
-
private instance;
|
|
9
|
-
constructor(options: CreateAxiosDefaults);
|
|
10
|
-
requestInterceptors(config: InternalAxiosRequestConfig): InternalAxiosRequestConfig<any>;
|
|
11
|
-
responseInterceptors(response: AxiosResponse): any;
|
|
12
|
-
private request;
|
|
13
|
-
get<T = any>({ ...config }: AxiosRequestConfig): Promise<IReqBoay<T>>;
|
|
14
|
-
post<T = any>({ ...config }: AxiosRequestConfig): Promise<IReqBoay<T>>;
|
|
15
|
-
}
|
|
16
|
-
export declare const request: HttpRequest;
|
|
17
|
-
export {};
|
package/dist/utils/request.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.request = void 0;
|
|
7
|
-
const axios_1 = __importDefault(require("axios"));
|
|
8
|
-
class HttpRequest {
|
|
9
|
-
constructor(options) {
|
|
10
|
-
this.instance = axios_1.default.create(options);
|
|
11
|
-
this.instance.interceptors.request.use(this.requestInterceptors);
|
|
12
|
-
this.instance.interceptors.response.use(this.responseInterceptors);
|
|
13
|
-
}
|
|
14
|
-
requestInterceptors(config) {
|
|
15
|
-
return config;
|
|
16
|
-
}
|
|
17
|
-
responseInterceptors(response) {
|
|
18
|
-
return response.data;
|
|
19
|
-
}
|
|
20
|
-
request(config) {
|
|
21
|
-
return new Promise((resolve, reject) => {
|
|
22
|
-
this.instance
|
|
23
|
-
.request(config)
|
|
24
|
-
.then((res) => {
|
|
25
|
-
console.log('request:', res);
|
|
26
|
-
resolve(res);
|
|
27
|
-
})
|
|
28
|
-
.catch((err) => {
|
|
29
|
-
reject(err.message);
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
get({ ...config }) {
|
|
34
|
-
return this.request({
|
|
35
|
-
...config,
|
|
36
|
-
method: 'GET'
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
post({ ...config }) {
|
|
40
|
-
return this.request({
|
|
41
|
-
...config,
|
|
42
|
-
method: 'POST'
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
exports.request = new HttpRequest({
|
|
47
|
-
baseURL: ``,
|
|
48
|
-
timeout: 20000
|
|
49
|
-
});
|