swagger2api-v3 1.1.5 → 1.1.6
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 +230 -230
- package/dist/core/parser.js +6 -2
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +91 -16
- package/package.json +68 -68
package/README.md
CHANGED
|
@@ -1,230 +1,230 @@
|
|
|
1
|
-
# Swagger2API-v3
|
|
2
|
-
|
|
3
|
-
English | [中文](./README_CN.md)
|
|
4
|
-
|
|
5
|
-
A powerful command-line tool for automatically generating TypeScript or JavaScript interface code from OpenAPI 3.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 generates a `.swagger.config.json` configuration file:
|
|
37
|
-
|
|
38
|
-
```json
|
|
39
|
-
{
|
|
40
|
-
"input": "https://petstore.swagger.io/v2/swagger.json",
|
|
41
|
-
"output": "./src/api",
|
|
42
|
-
"importTemplate": "import { request } from '@/utils/request';",
|
|
43
|
-
"generator": "typescript",
|
|
44
|
-
"requestStyle": "generic",
|
|
45
|
-
"groupByTags": true,
|
|
46
|
-
"overwrite": true,
|
|
47
|
-
"prefix": "",
|
|
48
|
-
"lint": "prettier --write",
|
|
49
|
-
"methodNameIgnorePrefix": [],
|
|
50
|
-
"addMethodSuffix": true,
|
|
51
|
-
"options": {
|
|
52
|
-
"addComments": true
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### 3. Generate Interface Code
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
npx swagger2api-v3 generate
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## ⚙️ Configuration Options
|
|
64
|
-
|
|
65
|
-
| Option | Type | Default | Description |
|
|
66
|
-
| ------------------------ | --------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
67
|
-
| `input` | string | - | Swagger JSON file path or URL |
|
|
68
|
-
| `output` | string | `'./src/api'` | Output directory for generated code |
|
|
69
|
-
| `generator` | string | `'typescript'` | Code generator type. Supports `'typescript'` and `'javascript'`. `'javascript'` outputs `.js` files and skips type file generation |
|
|
70
|
-
| `groupByTags` | boolean | `true` | Whether to group files by tags |
|
|
71
|
-
| `overwrite` | boolean | `true` | Whether to overwrite existing files |
|
|
72
|
-
| `prefix` | string | `''` | Common prefix for API paths |
|
|
73
|
-
| `importTemplate` | string | - | Import statement template for request function |
|
|
74
|
-
| `requestStyle` | 'method' \| 'generic' | `'generic'` | Request call style: `method` uses `request.get/post`, `generic` uses `request({ method })` |
|
|
75
|
-
| `lint` | string | - | Code formatting command (optional) |
|
|
76
|
-
| `methodNameIgnorePrefix` | string[] | `[]` | Array of prefixes to ignore when generating method names. For example, `['api', 'auth']` will transform `apiGetName` to `getName` and `authUserInfo` to `userInfo` |
|
|
77
|
-
| `addMethodSuffix` | boolean | `true` | Whether to add HTTP method suffix to generated function names. `true` generates `userListPost`, `false` generates `userList` |
|
|
78
|
-
| `options.addComments` | boolean | `true` | Whether to add detailed comments |
|
|
79
|
-
|
|
80
|
-
## 📁 Generated File Structure
|
|
81
|
-
|
|
82
|
-
### Grouped by Tags (Recommended)
|
|
83
|
-
|
|
84
|
-
```
|
|
85
|
-
src/api/
|
|
86
|
-
├── types.ts # Data type definitions (TypeScript mode only)
|
|
87
|
-
├── user/ # User-related APIs
|
|
88
|
-
│ └── index.ts
|
|
89
|
-
├── auth/ # Auth-related APIs
|
|
90
|
-
│ └── index.ts
|
|
91
|
-
└── index.ts # Entry file
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### JavaScript Output
|
|
95
|
-
|
|
96
|
-
When `generator: 'javascript'` is set:
|
|
97
|
-
|
|
98
|
-
- Outputs `.js` files (`index.js`, `api.js`, `user/index.js`, etc.)
|
|
99
|
-
- Does not generate a `types.ts` file
|
|
100
|
-
- Removes TypeScript-specific syntax (types, `import type`, generics like `<T>`)
|
|
101
|
-
|
|
102
|
-
Example generated API function (method style):
|
|
103
|
-
|
|
104
|
-
```javascript
|
|
105
|
-
export const codeAuth = (data, config) => {
|
|
106
|
-
return request.post({ url: '/api/auth/codeAuth', data, ...config });
|
|
107
|
-
};
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
Example generated API function (generic style):
|
|
111
|
-
|
|
112
|
-
```javascript
|
|
113
|
-
export const codeAuth = (data, config) => {
|
|
114
|
-
return request({
|
|
115
|
-
url: '/api/auth/codeAuth',
|
|
116
|
-
method: 'POST',
|
|
117
|
-
data,
|
|
118
|
-
...config
|
|
119
|
-
});
|
|
120
|
-
};
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
### Not Grouped
|
|
124
|
-
|
|
125
|
-
```
|
|
126
|
-
src/api/
|
|
127
|
-
├── types.ts # Data type definitions
|
|
128
|
-
├── api.ts # All API interfaces
|
|
129
|
-
└── index.ts # Entry file
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## 💡 Usage Examples
|
|
133
|
-
|
|
134
|
-
### Generated Type Definitions
|
|
135
|
-
|
|
136
|
-
```typescript
|
|
137
|
-
// types.ts
|
|
138
|
-
export interface LoginDto {
|
|
139
|
-
/** Account */
|
|
140
|
-
account: string;
|
|
141
|
-
/** Password */
|
|
142
|
-
password: string;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export interface UserInfo {
|
|
146
|
-
/** User ID */
|
|
147
|
-
id: string;
|
|
148
|
-
/** Username */
|
|
149
|
-
username: string;
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### Generated API Interfaces
|
|
154
|
-
|
|
155
|
-
```typescript
|
|
156
|
-
// authController/index.ts
|
|
157
|
-
import { request } from '@/utils/request';
|
|
158
|
-
import type { LoginDto, LoginRespDto } from '../types';
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Login
|
|
162
|
-
* @param data Login parameters
|
|
163
|
-
* @param config Optional request configuration
|
|
164
|
-
*/
|
|
165
|
-
export const authControllerLoginPost = (data: LoginDto, config?: any) => {
|
|
166
|
-
return request.post<LoginRespDto>({
|
|
167
|
-
url: '/admin/auth/login',
|
|
168
|
-
data,
|
|
169
|
-
...config
|
|
170
|
-
});
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
// When requestStyle is set to 'generic':
|
|
174
|
-
export const authControllerLoginPost2 = (data: LoginDto, config?: any) => {
|
|
175
|
-
return request<LoginRespDto>({
|
|
176
|
-
url: '/admin/auth/login',
|
|
177
|
-
data,
|
|
178
|
-
method: 'POST',
|
|
179
|
-
...config
|
|
180
|
-
});
|
|
181
|
-
};
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
## 🔧 CLI Commands
|
|
185
|
-
|
|
186
|
-
```bash
|
|
187
|
-
# Initialize configuration file
|
|
188
|
-
npx swagger2api-v3 init [--force]
|
|
189
|
-
|
|
190
|
-
# Generate interface code
|
|
191
|
-
npx swagger2api-v3 generate [--config <path>]
|
|
192
|
-
|
|
193
|
-
# Validate configuration file
|
|
194
|
-
npx swagger2api-v3 validate [--config <path>]
|
|
195
|
-
|
|
196
|
-
# Show help
|
|
197
|
-
npx swagger2api-v3 --help
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
## 📝 NPM Scripts
|
|
201
|
-
|
|
202
|
-
Add to `package.json`:
|
|
203
|
-
|
|
204
|
-
```json
|
|
205
|
-
{
|
|
206
|
-
"scripts": {
|
|
207
|
-
"api:generate": "swagger2api-v3 generate",
|
|
208
|
-
"api:init": "swagger2api-v3 init",
|
|
209
|
-
"api:validate": "swagger2api-v3 validate"
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
## 🎨 Code Formatting
|
|
215
|
-
|
|
216
|
-
Support automatic execution of formatting commands after generation:
|
|
217
|
-
|
|
218
|
-
```json
|
|
219
|
-
{
|
|
220
|
-
"lint": "prettier --write"
|
|
221
|
-
}
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
## 🤝 Contributing
|
|
225
|
-
|
|
226
|
-
If you encounter any problems or have suggestions, please feel free to [submit an issue](https://github.com/xiaoyang33/swagger2api-v3/issues) on GitHub. Pull Requests are also welcome!
|
|
227
|
-
|
|
228
|
-
## 📄 License
|
|
229
|
-
|
|
230
|
-
MIT License
|
|
1
|
+
# Swagger2API-v3
|
|
2
|
+
|
|
3
|
+
English | [中文](./README_CN.md)
|
|
4
|
+
|
|
5
|
+
A powerful command-line tool for automatically generating TypeScript or JavaScript interface code from OpenAPI 3.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 generates a `.swagger.config.json` configuration file:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"input": "https://petstore.swagger.io/v2/swagger.json",
|
|
41
|
+
"output": "./src/api",
|
|
42
|
+
"importTemplate": "import { request } from '@/utils/request';",
|
|
43
|
+
"generator": "typescript",
|
|
44
|
+
"requestStyle": "generic",
|
|
45
|
+
"groupByTags": true,
|
|
46
|
+
"overwrite": true,
|
|
47
|
+
"prefix": "",
|
|
48
|
+
"lint": "prettier --write",
|
|
49
|
+
"methodNameIgnorePrefix": [],
|
|
50
|
+
"addMethodSuffix": true,
|
|
51
|
+
"options": {
|
|
52
|
+
"addComments": true
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 3. Generate Interface Code
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx swagger2api-v3 generate
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## ⚙️ Configuration Options
|
|
64
|
+
|
|
65
|
+
| Option | Type | Default | Description |
|
|
66
|
+
| ------------------------ | --------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
67
|
+
| `input` | string | - | Swagger JSON file path or URL |
|
|
68
|
+
| `output` | string | `'./src/api'` | Output directory for generated code |
|
|
69
|
+
| `generator` | string | `'typescript'` | Code generator type. Supports `'typescript'` and `'javascript'`. `'javascript'` outputs `.js` files and skips type file generation |
|
|
70
|
+
| `groupByTags` | boolean | `true` | Whether to group files by tags |
|
|
71
|
+
| `overwrite` | boolean | `true` | Whether to overwrite existing files |
|
|
72
|
+
| `prefix` | string | `''` | Common prefix for API paths |
|
|
73
|
+
| `importTemplate` | string | - | Import statement template for request function |
|
|
74
|
+
| `requestStyle` | 'method' \| 'generic' | `'generic'` | Request call style: `method` uses `request.get/post`, `generic` uses `request({ method })` |
|
|
75
|
+
| `lint` | string | - | Code formatting command (optional) |
|
|
76
|
+
| `methodNameIgnorePrefix` | string[] | `[]` | Array of prefixes to ignore when generating method names. For example, `['api', 'auth']` will transform `apiGetName` to `getName` and `authUserInfo` to `userInfo` |
|
|
77
|
+
| `addMethodSuffix` | boolean | `true` | Whether to add HTTP method suffix to generated function names. `true` generates `userListPost`, `false` generates `userList` |
|
|
78
|
+
| `options.addComments` | boolean | `true` | Whether to add detailed comments |
|
|
79
|
+
|
|
80
|
+
## 📁 Generated File Structure
|
|
81
|
+
|
|
82
|
+
### Grouped by Tags (Recommended)
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
src/api/
|
|
86
|
+
├── types.ts # Data type definitions (TypeScript mode only)
|
|
87
|
+
├── user/ # User-related APIs
|
|
88
|
+
│ └── index.ts
|
|
89
|
+
├── auth/ # Auth-related APIs
|
|
90
|
+
│ └── index.ts
|
|
91
|
+
└── index.ts # Entry file
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### JavaScript Output
|
|
95
|
+
|
|
96
|
+
When `generator: 'javascript'` is set:
|
|
97
|
+
|
|
98
|
+
- Outputs `.js` files (`index.js`, `api.js`, `user/index.js`, etc.)
|
|
99
|
+
- Does not generate a `types.ts` file
|
|
100
|
+
- Removes TypeScript-specific syntax (types, `import type`, generics like `<T>`)
|
|
101
|
+
|
|
102
|
+
Example generated API function (method style):
|
|
103
|
+
|
|
104
|
+
```javascript
|
|
105
|
+
export const codeAuth = (data, config) => {
|
|
106
|
+
return request.post({ url: '/api/auth/codeAuth', data, ...config });
|
|
107
|
+
};
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Example generated API function (generic style):
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
export const codeAuth = (data, config) => {
|
|
114
|
+
return request({
|
|
115
|
+
url: '/api/auth/codeAuth',
|
|
116
|
+
method: 'POST',
|
|
117
|
+
data,
|
|
118
|
+
...config
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Not Grouped
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
src/api/
|
|
127
|
+
├── types.ts # Data type definitions
|
|
128
|
+
├── api.ts # All API interfaces
|
|
129
|
+
└── index.ts # Entry file
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## 💡 Usage Examples
|
|
133
|
+
|
|
134
|
+
### Generated Type Definitions
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
// types.ts
|
|
138
|
+
export interface LoginDto {
|
|
139
|
+
/** Account */
|
|
140
|
+
account: string;
|
|
141
|
+
/** Password */
|
|
142
|
+
password: string;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface UserInfo {
|
|
146
|
+
/** User ID */
|
|
147
|
+
id: string;
|
|
148
|
+
/** Username */
|
|
149
|
+
username: string;
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Generated API Interfaces
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
// authController/index.ts
|
|
157
|
+
import { request } from '@/utils/request';
|
|
158
|
+
import type { LoginDto, LoginRespDto } from '../types';
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Login
|
|
162
|
+
* @param data Login parameters
|
|
163
|
+
* @param config Optional request configuration
|
|
164
|
+
*/
|
|
165
|
+
export const authControllerLoginPost = (data: LoginDto, config?: any) => {
|
|
166
|
+
return request.post<LoginRespDto>({
|
|
167
|
+
url: '/admin/auth/login',
|
|
168
|
+
data,
|
|
169
|
+
...config
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// When requestStyle is set to 'generic':
|
|
174
|
+
export const authControllerLoginPost2 = (data: LoginDto, config?: any) => {
|
|
175
|
+
return request<LoginRespDto>({
|
|
176
|
+
url: '/admin/auth/login',
|
|
177
|
+
data,
|
|
178
|
+
method: 'POST',
|
|
179
|
+
...config
|
|
180
|
+
});
|
|
181
|
+
};
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## 🔧 CLI Commands
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
# Initialize configuration file
|
|
188
|
+
npx swagger2api-v3 init [--force]
|
|
189
|
+
|
|
190
|
+
# Generate interface code
|
|
191
|
+
npx swagger2api-v3 generate [--config <path>]
|
|
192
|
+
|
|
193
|
+
# Validate configuration file
|
|
194
|
+
npx swagger2api-v3 validate [--config <path>]
|
|
195
|
+
|
|
196
|
+
# Show help
|
|
197
|
+
npx swagger2api-v3 --help
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## 📝 NPM Scripts
|
|
201
|
+
|
|
202
|
+
Add to `package.json`:
|
|
203
|
+
|
|
204
|
+
```json
|
|
205
|
+
{
|
|
206
|
+
"scripts": {
|
|
207
|
+
"api:generate": "swagger2api-v3 generate",
|
|
208
|
+
"api:init": "swagger2api-v3 init",
|
|
209
|
+
"api:validate": "swagger2api-v3 validate"
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## 🎨 Code Formatting
|
|
215
|
+
|
|
216
|
+
Support automatic execution of formatting commands after generation:
|
|
217
|
+
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"lint": "prettier --write"
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## 🤝 Contributing
|
|
225
|
+
|
|
226
|
+
If you encounter any problems or have suggestions, please feel free to [submit an issue](https://github.com/xiaoyang33/swagger2api-v3/issues) on GitHub. Pull Requests are also welcome!
|
|
227
|
+
|
|
228
|
+
## 📄 License
|
|
229
|
+
|
|
230
|
+
MIT License
|
package/dist/core/parser.js
CHANGED
|
@@ -180,7 +180,9 @@ class SwaggerParser {
|
|
|
180
180
|
const properties = Object.entries(schema.properties)
|
|
181
181
|
.map(([key, value]) => {
|
|
182
182
|
const optional = schema.required?.includes(key) ? '' : '?';
|
|
183
|
-
|
|
183
|
+
let type = (0, utils_1.swaggerTypeToTsType)(value, allSchemas);
|
|
184
|
+
if (optional === '?')
|
|
185
|
+
type = (0, utils_1.stripNullFromUnion)(type);
|
|
184
186
|
const comment = value.description
|
|
185
187
|
? ` /** ${value.description} */`
|
|
186
188
|
: '';
|
|
@@ -203,7 +205,9 @@ class SwaggerParser {
|
|
|
203
205
|
// 优先使用 x-enum-varnames 或 x-enumNames 扩展字段
|
|
204
206
|
if ((schema['x-enum-varnames'] && schema['x-enum-varnames'][index]) ||
|
|
205
207
|
(schema['x-enumNames'] && schema['x-enumNames'][index])) {
|
|
206
|
-
key =
|
|
208
|
+
key =
|
|
209
|
+
schema['x-enum-varnames']?.[index] ||
|
|
210
|
+
schema['x-enumNames']?.[index];
|
|
207
211
|
}
|
|
208
212
|
else if (/^\d+$/.test(value)) {
|
|
209
213
|
// 对于数字枚举,使用 VALUE_ 前缀
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ export declare function stripMethodNamePrefixes(methodName: string, prefixes?: s
|
|
|
41
41
|
* @returns 移除后缀后的函数名
|
|
42
42
|
*/
|
|
43
43
|
export declare function removeMethodSuffix(functionName: string, method: string): string;
|
|
44
|
+
export declare function stripNullFromUnion(typeStr: string): string;
|
|
44
45
|
/**
|
|
45
46
|
* 将Swagger类型转换为TypeScript类型
|
|
46
47
|
* @param schema Swagger模式
|
package/dist/utils/index.js
CHANGED
|
@@ -42,6 +42,7 @@ exports.toPascalCase = toPascalCase;
|
|
|
42
42
|
exports.toCamelCase = toCamelCase;
|
|
43
43
|
exports.stripMethodNamePrefixes = stripMethodNamePrefixes;
|
|
44
44
|
exports.removeMethodSuffix = removeMethodSuffix;
|
|
45
|
+
exports.stripNullFromUnion = stripNullFromUnion;
|
|
45
46
|
exports.swaggerTypeToTsType = swaggerTypeToTsType;
|
|
46
47
|
exports.generateParameterTypes = generateParameterTypes;
|
|
47
48
|
exports.ensureDirectoryExists = ensureDirectoryExists;
|
|
@@ -165,6 +166,49 @@ function removeMethodSuffix(functionName, method) {
|
|
|
165
166
|
}
|
|
166
167
|
return functionName;
|
|
167
168
|
}
|
|
169
|
+
function stripNullFromUnion(typeStr) {
|
|
170
|
+
if (!typeStr)
|
|
171
|
+
return 'any';
|
|
172
|
+
const parts = [];
|
|
173
|
+
let current = '';
|
|
174
|
+
let parenDepth = 0;
|
|
175
|
+
let angleDepth = 0;
|
|
176
|
+
let braceDepth = 0;
|
|
177
|
+
let bracketDepth = 0;
|
|
178
|
+
for (let i = 0; i < typeStr.length; i++) {
|
|
179
|
+
const ch = typeStr[i];
|
|
180
|
+
if (ch === '(')
|
|
181
|
+
parenDepth++;
|
|
182
|
+
else if (ch === ')')
|
|
183
|
+
parenDepth = Math.max(0, parenDepth - 1);
|
|
184
|
+
else if (ch === '<')
|
|
185
|
+
angleDepth++;
|
|
186
|
+
else if (ch === '>')
|
|
187
|
+
angleDepth = Math.max(0, angleDepth - 1);
|
|
188
|
+
else if (ch === '{')
|
|
189
|
+
braceDepth++;
|
|
190
|
+
else if (ch === '}')
|
|
191
|
+
braceDepth = Math.max(0, braceDepth - 1);
|
|
192
|
+
else if (ch === '[')
|
|
193
|
+
bracketDepth++;
|
|
194
|
+
else if (ch === ']')
|
|
195
|
+
bracketDepth = Math.max(0, bracketDepth - 1);
|
|
196
|
+
const isTopLevel = parenDepth === 0 &&
|
|
197
|
+
angleDepth === 0 &&
|
|
198
|
+
braceDepth === 0 &&
|
|
199
|
+
bracketDepth === 0;
|
|
200
|
+
if (ch === '|' && isTopLevel) {
|
|
201
|
+
parts.push(current.trim());
|
|
202
|
+
current = '';
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
current += ch;
|
|
206
|
+
}
|
|
207
|
+
if (current.trim())
|
|
208
|
+
parts.push(current.trim());
|
|
209
|
+
const normalized = Array.from(new Set(parts.filter((p) => p && p !== 'null')));
|
|
210
|
+
return normalized.length > 0 ? normalized.join(' | ') : 'any';
|
|
211
|
+
}
|
|
168
212
|
/**
|
|
169
213
|
* 将Swagger类型转换为TypeScript类型
|
|
170
214
|
* @param schema Swagger模式
|
|
@@ -190,7 +234,7 @@ function swaggerTypeToTsType(schema, schemas) {
|
|
|
190
234
|
// 这里假设泛型参数是 properties 中的第一个属性
|
|
191
235
|
const propertyTypes = [];
|
|
192
236
|
for (const [propName, propSchema] of Object.entries(secondSchema.properties)) {
|
|
193
|
-
const propType = swaggerTypeToTsType(propSchema);
|
|
237
|
+
const propType = swaggerTypeToTsType(propSchema, schemas);
|
|
194
238
|
propertyTypes.push(propType);
|
|
195
239
|
}
|
|
196
240
|
// 如果只有一个属性,直接作为泛型参数
|
|
@@ -202,7 +246,9 @@ function swaggerTypeToTsType(schema, schemas) {
|
|
|
202
246
|
const combinedType = `{ ${Object.entries(secondSchema.properties)
|
|
203
247
|
.map(([key, value]) => {
|
|
204
248
|
const optional = secondSchema.required?.includes(key) ? '' : '?';
|
|
205
|
-
|
|
249
|
+
let type = swaggerTypeToTsType(value, schemas);
|
|
250
|
+
if (optional === '?')
|
|
251
|
+
type = stripNullFromUnion(type);
|
|
206
252
|
return `${key}${optional}: ${type}`;
|
|
207
253
|
})
|
|
208
254
|
.join('; ')} }`;
|
|
@@ -226,21 +272,25 @@ function swaggerTypeToTsType(schema, schemas) {
|
|
|
226
272
|
}
|
|
227
273
|
// 处理 anyOf 或 oneOf
|
|
228
274
|
else if (schema.anyOf || schema.oneOf) {
|
|
229
|
-
const types = (schema.anyOf || schema.oneOf)
|
|
230
|
-
.map((s) => {
|
|
275
|
+
const types = (schema.anyOf || schema.oneOf).map((s) => {
|
|
231
276
|
// 特殊处理 type: 'null'
|
|
232
277
|
if (s.type === 'null')
|
|
233
278
|
return 'null';
|
|
234
|
-
return swaggerTypeToTsType(s);
|
|
235
|
-
})
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if (uniqueTypes.length > 0) {
|
|
240
|
-
baseType = uniqueTypes.join(' | ');
|
|
279
|
+
return swaggerTypeToTsType(s, schemas);
|
|
280
|
+
});
|
|
281
|
+
// 如果包含 any,则直接返回 any
|
|
282
|
+
if (types.includes('any')) {
|
|
283
|
+
baseType = 'any';
|
|
241
284
|
}
|
|
242
285
|
else {
|
|
243
|
-
|
|
286
|
+
// 去重
|
|
287
|
+
const uniqueTypes = Array.from(new Set(types));
|
|
288
|
+
if (uniqueTypes.length > 0) {
|
|
289
|
+
baseType = uniqueTypes.join(' | ');
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
baseType = 'any';
|
|
293
|
+
}
|
|
244
294
|
}
|
|
245
295
|
}
|
|
246
296
|
// 处理引用类型
|
|
@@ -248,7 +298,10 @@ function swaggerTypeToTsType(schema, schemas) {
|
|
|
248
298
|
const refName = schema.$ref.split('/').pop();
|
|
249
299
|
baseType = sanitizeTypeName(refName || 'any');
|
|
250
300
|
// 如果提供了 schemas 上下文,检查被引用的 schema 是否是数组类型
|
|
251
|
-
if (schemas &&
|
|
301
|
+
if (schemas &&
|
|
302
|
+
refName &&
|
|
303
|
+
typeof schema.$ref === 'string' &&
|
|
304
|
+
schema.$ref.startsWith('#/')) {
|
|
252
305
|
const referencedSchema = schemas[refName];
|
|
253
306
|
if (referencedSchema && referencedSchema.type === 'array') {
|
|
254
307
|
// 被引用的 schema 是数组类型,添加 []
|
|
@@ -258,8 +311,24 @@ function swaggerTypeToTsType(schema, schemas) {
|
|
|
258
311
|
}
|
|
259
312
|
// 处理数组类型
|
|
260
313
|
else if (schema.type === 'array') {
|
|
261
|
-
const
|
|
262
|
-
|
|
314
|
+
const itemSchema = schema.items;
|
|
315
|
+
const itemType = swaggerTypeToTsType(itemSchema, schemas);
|
|
316
|
+
if (itemSchema?.$ref &&
|
|
317
|
+
schemas &&
|
|
318
|
+
typeof itemSchema.$ref === 'string' &&
|
|
319
|
+
itemSchema.$ref.startsWith('#/')) {
|
|
320
|
+
const refName = itemSchema.$ref.split('/').pop();
|
|
321
|
+
const referencedSchema = refName ? schemas[refName] : undefined;
|
|
322
|
+
if (referencedSchema?.type === 'array') {
|
|
323
|
+
baseType = itemType;
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
baseType = `${itemType}[]`;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
baseType = `${itemType}[]`;
|
|
331
|
+
}
|
|
263
332
|
}
|
|
264
333
|
// 处理对象类型
|
|
265
334
|
else if (schema.type === 'object') {
|
|
@@ -267,7 +336,9 @@ function swaggerTypeToTsType(schema, schemas) {
|
|
|
267
336
|
const properties = Object.entries(schema.properties)
|
|
268
337
|
.map(([key, value]) => {
|
|
269
338
|
const optional = schema.required?.includes(key) ? '' : '?';
|
|
270
|
-
|
|
339
|
+
let type = swaggerTypeToTsType(value, schemas);
|
|
340
|
+
if (optional === '?')
|
|
341
|
+
type = stripNullFromUnion(type);
|
|
271
342
|
return ` ${key}${optional}: ${type};`;
|
|
272
343
|
})
|
|
273
344
|
.join('\n');
|
|
@@ -308,6 +379,10 @@ function swaggerTypeToTsType(schema, schemas) {
|
|
|
308
379
|
}
|
|
309
380
|
// 处理 nullable 属性
|
|
310
381
|
if (schema.nullable === true) {
|
|
382
|
+
if (baseType === 'any')
|
|
383
|
+
return 'any';
|
|
384
|
+
if (baseType.includes('null'))
|
|
385
|
+
return baseType;
|
|
311
386
|
return `${baseType} | null`;
|
|
312
387
|
}
|
|
313
388
|
return baseType;
|
package/package.json
CHANGED
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "swagger2api-v3",
|
|
3
|
-
"version": "1.1.
|
|
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
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "swagger2api-v3",
|
|
3
|
+
"version": "1.1.6",
|
|
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
|
+
}
|