anl 26.107.0 → 26.107.1
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.ar.md +59 -59
- package/README.es.md +59 -59
- package/README.fr.md +106 -106
- package/README.jp.md +56 -56
- package/README.md +131 -67
- package/README.ru.md +56 -56
- package/README.zh.md +144 -78
- package/lib/package.json.js +1 -1
- package/lib/src/build-type/core/get-data.js +1 -1
- package/lib/src/build-type/core/path.js +1 -1
- package/lib/src/build-type/index.js +1 -1
- package/package.json +1 -1
package/README.zh.md
CHANGED
|
@@ -107,17 +107,20 @@ $ anl type
|
|
|
107
107
|
"saveEnumFolderPath": "apps/enums",
|
|
108
108
|
"importEnumPath": "../../enums",
|
|
109
109
|
"requestMethodsImportPath": "./fetch",
|
|
110
|
-
"dataLevel": "serve",
|
|
111
|
-
"parameterSeparator": "_",
|
|
112
110
|
"formatting": {
|
|
113
111
|
"indentation": "\t",
|
|
114
112
|
"lineEnding": "\n"
|
|
115
113
|
},
|
|
116
|
-
"
|
|
114
|
+
"enmuConfig": {
|
|
115
|
+
"erasableSyntaxOnly": false,
|
|
116
|
+
"varnames": "enum-varnames",
|
|
117
|
+
"comment": "enum-descriptions"
|
|
118
|
+
},
|
|
119
|
+
"swaggerConfig": {
|
|
117
120
|
"url": "https://generator3.swagger.io/openapi2.json",
|
|
118
121
|
"apiListFileName": "index.ts",
|
|
119
122
|
"publicPrefix": "/api",
|
|
120
|
-
"
|
|
123
|
+
"modulePrefix": "/gateway",
|
|
121
124
|
"dataLevel": "serve",
|
|
122
125
|
"parameterSeparator": "_",
|
|
123
126
|
"headers": {
|
|
@@ -126,15 +129,12 @@ $ anl type
|
|
|
126
129
|
"includeInterface": [
|
|
127
130
|
{
|
|
128
131
|
"path": "/api/user",
|
|
129
|
-
"method": "get"
|
|
132
|
+
"method": "get",
|
|
133
|
+
"dataLevel": "data"
|
|
130
134
|
}
|
|
131
|
-
]
|
|
135
|
+
],
|
|
136
|
+
"excludeInterface":[]
|
|
132
137
|
},
|
|
133
|
-
"enmuConfig": {
|
|
134
|
-
"erasableSyntaxOnly": false,
|
|
135
|
-
"varnames": "enum-varnames",
|
|
136
|
-
"comment": "enum-descriptions"
|
|
137
|
-
}
|
|
138
138
|
}
|
|
139
139
|
```
|
|
140
140
|
|
|
@@ -152,26 +152,27 @@ $ anl type
|
|
|
152
152
|
"indentation": "\t",
|
|
153
153
|
"lineEnding": "\n"
|
|
154
154
|
},
|
|
155
|
-
"parameterSeparator": "_",
|
|
156
155
|
"enmuConfig": {
|
|
157
156
|
"erasableSyntaxOnly": false,
|
|
158
157
|
"varnames": "enum-varnames",
|
|
159
158
|
"comment": "enum-descriptions"
|
|
160
159
|
},
|
|
161
|
-
"
|
|
160
|
+
"swaggerConfig": [
|
|
162
161
|
{
|
|
163
162
|
"url": "https://generator3.swagger.io/openapi1.json",
|
|
164
163
|
"apiListFileName": "op.ts",
|
|
165
|
-
"
|
|
164
|
+
"modulePrefix": "/forward",
|
|
166
165
|
"dataLevel": "serve",
|
|
167
166
|
"parameterSeparator": "_",
|
|
168
167
|
"headers": {},
|
|
169
168
|
"includeInterface": [
|
|
170
169
|
{
|
|
171
170
|
"path": "/op/trade/order/queryPage",
|
|
172
|
-
"method": "post"
|
|
171
|
+
"method": "post",
|
|
172
|
+
"dataLevel": "axios"
|
|
173
173
|
}
|
|
174
|
-
]
|
|
174
|
+
],
|
|
175
|
+
"excludeInterface": []
|
|
175
176
|
},
|
|
176
177
|
{
|
|
177
178
|
"url": "https://generator3.swagger.io/openapi2.json",
|
|
@@ -186,39 +187,39 @@ $ anl type
|
|
|
186
187
|
|
|
187
188
|
#### 配置项说明
|
|
188
189
|
|
|
189
|
-
| 配置项
|
|
190
|
-
|
|
|
191
|
-
| saveTypeFolderPath
|
|
192
|
-
| saveApiListFolderPath
|
|
193
|
-
| saveEnumFolderPath
|
|
194
|
-
| importEnumPath
|
|
195
|
-
| swaggerJsonUrl
|
|
196
|
-
|
|
|
197
|
-
|
|
|
198
|
-
|
|
|
199
|
-
|
|
|
200
|
-
|
|
|
201
|
-
|
|
|
202
|
-
|
|
|
203
|
-
|
|
|
204
|
-
|
|
|
205
|
-
|
|
|
206
|
-
| requestMethodsImportPath
|
|
207
|
-
| dataLevel
|
|
208
|
-
| formatting
|
|
209
|
-
| formatting.indentation
|
|
210
|
-
| formatting.lineEnding
|
|
211
|
-
| headers
|
|
212
|
-
| includeInterface
|
|
213
|
-
| excludeInterface
|
|
214
|
-
| publicPrefix
|
|
215
|
-
|
|
|
216
|
-
| apiListFileName
|
|
217
|
-
| enmuConfig
|
|
218
|
-
| enmuConfig.erasableSyntaxOnly
|
|
219
|
-
| enmuConfig.varnames
|
|
220
|
-
| enmuConfig.comment
|
|
221
|
-
| parameterSeparator
|
|
190
|
+
| 配置项 | 类型 | 必填 | 说明 |
|
|
191
|
+
| ---------------------------------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
|
|
192
|
+
| saveTypeFolderPath | string | 是 | 类型定义文件保存路径 |
|
|
193
|
+
| saveApiListFolderPath | string | 是 | API 请求函数文件保存路径 |
|
|
194
|
+
| saveEnumFolderPath | string | 是 | 枚举数据文件保存路径 |
|
|
195
|
+
| importEnumPath | string | 是 | 枚举导入路径(apps/types/models/\*.ts 中 enum 文件的引用的路径) |
|
|
196
|
+
| swaggerJsonUrl | string | 否 | Swagger JSON 文档地址(已迁移到 `swaggerConfig.url`,保留用于兼容旧版配置)**后面迭代版本会删除该字段** |
|
|
197
|
+
| swaggerConfig | object \| Array<object> | 否 | Swagger 服务器配置。单个服务器可直接填写对象,多个服务器使用数组。每个服务器可配置 `url`、`publicPrefix`、`modulePrefix`、`apiListFileName`、`headers`、`dataLevel`、`parameterSeparator`、`includeInterface`、`excludeInterface`<br />这个字段 对应 单 Swagger 服务器配置 与 多 Swagger 服务器配置 示例,请向上滚动查看 |
|
|
198
|
+
| swaggerConfig[].url | string | 是 | Swagger JSON 文档地址 |
|
|
199
|
+
| swaggerConfig[].publicPrefix | string | 否 | url path 上的公共前缀,例如:api/users、api/users/{id} ,api 就是公共前缀 |
|
|
200
|
+
| swaggerConfig[].modulePrefix | string | 否 | 请求路径前缀(可以理解为模块名),会自动添加到每个 API 请求路径前面。<br />例如:`modulePrefix: "/forward"` 时,<br />`/publicPrefix/modulePrefix/user` , 会变成 `/publicPrefix/forward/user` |
|
|
201
|
+
| swaggerConfig[].apiListFileName | string | 否 | API 列表文件名,默认为 `index.ts`。多个服务器时,每个服务器的API 列表文件名必须唯一 |
|
|
202
|
+
| swaggerConfig[].headers | object | 否 | 该服务器的请求头配置 |
|
|
203
|
+
| swaggerConfig[].dataLevel | 'data' \| 'serve' \| 'axios' | 否 | 该服务器的接口返回数据层级。若未设置,使用全局 `dataLevel` 配置 |
|
|
204
|
+
| swaggerConfig[].parameterSeparator | '$' \| '\_' | 否 | 该服务器生成 API 名称和类型名称时使用的分隔符。若未设置,使用全局 `parameterSeparator` 配置 |
|
|
205
|
+
| swaggerConfig[].includeInterface | Array<{path: string, method: string, dataLevel?: 'data' \| 'serve' \| 'axios'}> | 否 | 该服务器包含的接口列表。每个接口可单独配置 `dataLevel`,具有最高优先级。若未设置,使用全局 `includeInterface` 配置 |
|
|
206
|
+
| swaggerConfig[].excludeInterface | Array<{path: string, method: string}> | 否 | 该服务器排除的接口列表。若未设置,使用全局 `excludeInterface` 配置 |
|
|
207
|
+
| requestMethodsImportPath | string | 是 | 请求方法导入路径 |
|
|
208
|
+
| dataLevel | 'data' \| 'serve' \| 'axios' | 否 | 全局接口返回数据层级配置,默认值:`'serve'`。各服务器可单独配置覆盖 |
|
|
209
|
+
| formatting | object | 否 | 代码格式化配置 |
|
|
210
|
+
| formatting.indentation | string | 否 | 代码缩进字符,例如:`"\t"` 或 `" "`(两个空格) |
|
|
211
|
+
| formatting.lineEnding | string | 否 | 换行符,例如:`"\n"` (LF) 或 `"\r\n"` (CRLF) |
|
|
212
|
+
| headers | object | 否 | 全局请求头配置(已迁移到 `swaggerConfig`,保留用于兼容旧版配置) |
|
|
213
|
+
| includeInterface | Array<{path: string, method: string}> | 否 | 全局包含的接口:`saveApiListFolderPath`指定的接口列表文件,只会包含列表中的接口,与 `excludeInterface` 字段互斥。各服务器可单独配置覆盖 |
|
|
214
|
+
| excludeInterface | Array<{path: string, method: string}> | 否 | 全局排除的接口: `saveApiListFolderPath` 指定的接口列表文本,不存在该列表中的接口,与 `includeInterface` 互斥。各服务器可单独配置覆盖 |
|
|
215
|
+
| publicPrefix | string | 否 | 全局 url path 上的公共前缀(已迁移到 `swaggerConfig`,保留用于兼容旧版配置) |
|
|
216
|
+
| modulePrefix | string | 否 | 全局请求路径前缀(各服务器可单独配置覆盖) |
|
|
217
|
+
| apiListFileName | string | 否 | 全局 API 列表文件名,默认为 `index.ts`(已迁移到 `swaggerConfig`,保留用于兼容旧版配置) |
|
|
218
|
+
| enmuConfig | object | 是 | 枚举配置对象 |
|
|
219
|
+
| enmuConfig.erasableSyntaxOnly | boolean | 是 | 与 tsconfig.json 的 `compilerOptions.erasableSyntaxOnly` 选项保持一致。为 `true` 时,生成 const 对象而非 enum(仅类型语法)。默认值:`false` |
|
|
220
|
+
| enmuConfig.varnames | string | 否 | Swagger schema 中自定义枚举成员名所在的字段名。默认值:`enum-varnames`。 |
|
|
221
|
+
| enmuConfig.comment | string | 否 | Swagger schema 中自定义枚举描述所在的字段名(用于生成注释)。默认值:`enum-descriptions`。 |
|
|
222
|
+
| parameterSeparator | '$' \| '\_' | 否 | 全局生成 API 名称和类型名称时,路径段和参数之间使用的分隔符。例如,`/users/{userId}/posts` 使用分隔符 `'_'` 会生成 `users_userId_posts_GET`。默认值:`'_'`。各服务器可单独配置覆盖 |
|
|
222
223
|
|
|
223
224
|
#### 配置项与生成的文件对应关系
|
|
224
225
|
|
|
@@ -276,15 +277,19 @@ export const userDetailGet = (params: UserDetail_GET.Query) => GET<UserDetail_GE
|
|
|
276
277
|
|
|
277
278
|
工具支持全局配置和服务器级别配置,遵循以下优先级规则:
|
|
278
279
|
|
|
279
|
-
|
|
280
|
+
**优先级:接口级别配置 > 服务器级别配置 > 全局配置 > 默认值**
|
|
280
281
|
|
|
281
|
-
|
|
282
|
+
以下配置项支持多级优先级覆盖:
|
|
282
283
|
|
|
283
284
|
- `dataLevel`:接口返回数据层级
|
|
285
|
+
- **接口级别**:`includeInterface[].dataLevel` - 最高优先级
|
|
286
|
+
- **服务器级别**:`swaggerConfig[].dataLevel` - 次优先级
|
|
287
|
+
- **全局配置**:`dataLevel` - 基础优先级
|
|
288
|
+
- **默认值**:`'serve'`
|
|
284
289
|
- `parameterSeparator`:API 名称和类型名称的分隔符
|
|
285
290
|
- `includeInterface`:包含的接口列表
|
|
286
291
|
- `excludeInterface`:排除的接口列表
|
|
287
|
-
- `
|
|
292
|
+
- `modulePrefix`:请求路径前缀
|
|
288
293
|
- `publicPrefix`:URL 公共前缀
|
|
289
294
|
- `headers`:请求头配置
|
|
290
295
|
|
|
@@ -294,7 +299,7 @@ export const userDetailGet = (params: UserDetail_GET.Query) => GET<UserDetail_GE
|
|
|
294
299
|
{
|
|
295
300
|
"dataLevel": "serve",
|
|
296
301
|
"parameterSeparator": "_",
|
|
297
|
-
"
|
|
302
|
+
"swaggerConfig": [
|
|
298
303
|
{
|
|
299
304
|
"url": "http://api1.example.com/swagger.json",
|
|
300
305
|
"dataLevel": "data",
|
|
@@ -388,21 +393,50 @@ interface User {
|
|
|
388
393
|
// 函数返回: { code: 200, message: 'success', data: { id: 1, name: 'user' } }
|
|
389
394
|
```
|
|
390
395
|
|
|
396
|
+
**配置优先级:**
|
|
397
|
+
|
|
398
|
+
`dataLevel` 支持三级配置优先级:
|
|
399
|
+
|
|
400
|
+
```
|
|
401
|
+
接口级别 > 服务器级别 > 全局配置 > 默认值
|
|
402
|
+
```
|
|
403
|
+
|
|
391
404
|
**配置示例:**
|
|
392
405
|
|
|
393
406
|
```json
|
|
394
407
|
{
|
|
395
408
|
"dataLevel": "serve",
|
|
396
|
-
"
|
|
409
|
+
"swaggerConfig": [
|
|
397
410
|
{
|
|
398
411
|
"url": "http://api1.example.com/swagger.json",
|
|
399
|
-
"dataLevel": "data"
|
|
412
|
+
"dataLevel": "data",
|
|
413
|
+
"includeInterface": [
|
|
414
|
+
{
|
|
415
|
+
"path": "/api/user/detail",
|
|
416
|
+
"method": "get",
|
|
417
|
+
"dataLevel": "axios"
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
"path": "/api/user/list",
|
|
421
|
+
"method": "get"
|
|
422
|
+
}
|
|
423
|
+
]
|
|
400
424
|
}
|
|
401
425
|
]
|
|
402
426
|
}
|
|
403
427
|
```
|
|
404
428
|
|
|
405
|
-
|
|
429
|
+
在上面的配置中:
|
|
430
|
+
|
|
431
|
+
- `/api/user/detail` 接口使用 `dataLevel: "axios"`(接口级别配置,最高优先级)
|
|
432
|
+
- `/api/user/list` 接口使用 `dataLevel: "data"`(服务器级别配置)
|
|
433
|
+
- 其他服务器的接口使用 `dataLevel: "serve"`(全局配置)
|
|
434
|
+
|
|
435
|
+
> **注意**:
|
|
436
|
+
>
|
|
437
|
+
> - 接口级别的 `dataLevel` 配置具有最高优先级,适用于个别接口需要特殊处理的场景
|
|
438
|
+
> - 服务器级别的 `dataLevel` 配置会覆盖全局配置
|
|
439
|
+
> - 未配置时使用默认值 `'serve'`
|
|
406
440
|
|
|
407
441
|
#### 文件上传
|
|
408
442
|
|
|
@@ -457,7 +491,8 @@ export const uploadFile = (params: UploadFile.Body) =>
|
|
|
457
491
|
1. 包含特定接口
|
|
458
492
|
- 通过 `includeInterface` 配置项指定需要生成的接口
|
|
459
493
|
- 只会生成配置中指定的接口
|
|
460
|
-
- 配置格式为包含 `path`
|
|
494
|
+
- 配置格式为包含 `path`、`method` 和可选的 `dataLevel` 的对象数组
|
|
495
|
+
- 每个接口可以单独配置 `dataLevel`,具有最高优先级
|
|
461
496
|
|
|
462
497
|
2. 排除特定接口
|
|
463
498
|
- 通过 `excludeInterface` 配置项指定需要排除的接口
|
|
@@ -471,7 +506,8 @@ export const uploadFile = (params: UploadFile.Body) =>
|
|
|
471
506
|
"includeInterface": [
|
|
472
507
|
{
|
|
473
508
|
"path": "/api/user",
|
|
474
|
-
"method": "get"
|
|
509
|
+
"method": "get",
|
|
510
|
+
"dataLevel": "data"
|
|
475
511
|
}
|
|
476
512
|
],
|
|
477
513
|
"excludeInterface": [
|
|
@@ -489,8 +525,8 @@ export const uploadFile = (params: UploadFile.Body) =>
|
|
|
489
525
|
|
|
490
526
|
工具支持配置多个 Swagger 服务器,每个服务器可以独立配置:
|
|
491
527
|
|
|
492
|
-
- **单个服务器**:`
|
|
493
|
-
- **多个服务器**:`
|
|
528
|
+
- **单个服务器**:`swaggerConfig` 可以直接填写对象
|
|
529
|
+
- **多个服务器**:`swaggerConfig` 使用数组形式,每个服务器必须配置唯一的 `apiListFileName`
|
|
494
530
|
|
|
495
531
|
**工作原理:**
|
|
496
532
|
|
|
@@ -506,11 +542,11 @@ export const uploadFile = (params: UploadFile.Body) =>
|
|
|
506
542
|
- `parameterSeparator` - API 名称和类型名称的分隔符
|
|
507
543
|
- `includeInterface` - 包含的接口列表
|
|
508
544
|
- `excludeInterface` - 排除的接口列表
|
|
509
|
-
- `
|
|
545
|
+
- `modulePrefix` - 请求路径前缀
|
|
510
546
|
|
|
511
|
-
#### 路径前缀(
|
|
547
|
+
#### 路径前缀(modulePrefix)
|
|
512
548
|
|
|
513
|
-
`
|
|
549
|
+
`modulePrefix` 用于在所有 API 请求路径前自动添加前缀,这在以下场景特别有用:
|
|
514
550
|
|
|
515
551
|
1. **反向代理场景**:当后端服务通过反向代理转发时
|
|
516
552
|
2. **API 网关**:统一在路径前添加网关前缀
|
|
@@ -520,10 +556,10 @@ export const uploadFile = (params: UploadFile.Body) =>
|
|
|
520
556
|
|
|
521
557
|
```json
|
|
522
558
|
{
|
|
523
|
-
"
|
|
559
|
+
"swaggerConfig": [
|
|
524
560
|
{
|
|
525
561
|
"url": "http://api.example.com/swagger.json",
|
|
526
|
-
"
|
|
562
|
+
"modulePrefix": "/forward",
|
|
527
563
|
"apiListFileName": "api.ts"
|
|
528
564
|
}
|
|
529
565
|
]
|
|
@@ -541,18 +577,18 @@ export const apiUserListGet = (params: ApiUserList_GET.Query) => GET<ApiUserList
|
|
|
541
577
|
**与 publicPrefix 的区别:**
|
|
542
578
|
|
|
543
579
|
- `publicPrefix`:用于从接口路径中移除公共前缀(仅影响生成的函数名)
|
|
544
|
-
- `
|
|
580
|
+
- `modulePrefix`:用于在实际请求路径前添加前缀(影响运行时的请求 URL)
|
|
545
581
|
|
|
546
582
|
**配置示例:**
|
|
547
583
|
|
|
548
584
|
```json
|
|
549
585
|
{
|
|
550
|
-
"
|
|
586
|
+
"swaggerConfig": [
|
|
551
587
|
{
|
|
552
588
|
"url": "http://api1.example.com/swagger.json",
|
|
553
589
|
"apiListFileName": "api1.ts",
|
|
554
590
|
"publicPrefix": "/api/v1",
|
|
555
|
-
"
|
|
591
|
+
"modulePrefix": "/forward",
|
|
556
592
|
"dataLevel": "serve",
|
|
557
593
|
"parameterSeparator": "_",
|
|
558
594
|
"headers": {
|
|
@@ -582,7 +618,7 @@ export const apiUserListGet = (params: ApiUserList_GET.Query) => GET<ApiUserList
|
|
|
582
618
|
|
|
583
619
|
- 旧版配置(`swaggerJsonUrl`、`publicPrefix`、`headers`)仍然兼容
|
|
584
620
|
- 工具会自动检测旧版配置并提示迁移方式
|
|
585
|
-
- 建议迁移到新的 `
|
|
621
|
+
- 建议迁移到新的 `swaggerConfig` 配置以获得更好的灵活性
|
|
586
622
|
|
|
587
623
|
#### HTTP 方法支持
|
|
588
624
|
|
|
@@ -607,7 +643,7 @@ export const apiUserListGet = (params: ApiUserList_GET.Query) => GET<ApiUserList
|
|
|
607
643
|
4. 建议将生成的文件加入版本控制
|
|
608
644
|
5. 使用多 Swagger 服务器时,确保每个服务器的 `apiListFileName` 唯一,避免文件覆盖
|
|
609
645
|
6. 多个服务器配置时,类型定义和枚举会合并,如果不同服务器有同名类型,可能会产生冲突
|
|
610
|
-
7. 服务器级别的配置(`dataLevel`、`parameterSeparator`、`includeInterface`、`excludeInterface`、`
|
|
646
|
+
7. 服务器级别的配置(`dataLevel`、`parameterSeparator`、`includeInterface`、`excludeInterface`、`modulePrefix`)会覆盖全局配置
|
|
611
647
|
8. `includeInterface` 和 `excludeInterface` 不能同时配置,如果同时配置,会优先使用 `includeInterface`
|
|
612
648
|
|
|
613
649
|
### 常见问题
|
|
@@ -621,15 +657,15 @@ export const apiUserListGet = (params: ApiUserList_GET.Query) => GET<ApiUserList
|
|
|
621
657
|
- 检查 `requestMethodsImportPath` 配置是否正确
|
|
622
658
|
- 确认请求方法文件是否存在
|
|
623
659
|
|
|
624
|
-
3. **什么时候使用 `
|
|
660
|
+
3. **什么时候使用 `modulePrefix`?**
|
|
625
661
|
- 当你的 API 需要通过反向代理或网关访问时
|
|
626
662
|
- 例如:Swagger 中定义的是 `/api/user`,但实际请求需要是 `/gateway/api/user`
|
|
627
|
-
- 设置 `
|
|
663
|
+
- 设置 `modulePrefix: "/gateway"` 即可
|
|
628
664
|
|
|
629
|
-
4. **`publicPrefix` 和 `
|
|
665
|
+
4. **`publicPrefix` 和 `modulePrefix` 有什么区别?**
|
|
630
666
|
- `publicPrefix`:从接口路径中移除前缀,只影响生成的函数名
|
|
631
667
|
- 例如:`/api/user/list` 移除 `/api` 后,函数名为 `userListGet`
|
|
632
|
-
- `
|
|
668
|
+
- `modulePrefix`:在请求路径前添加前缀,影响实际请求的 URL
|
|
633
669
|
- 例如:`/api/user/list` 添加 `/forward` 后,请求 URL 为 `/forward/api/user/list`
|
|
634
670
|
|
|
635
671
|
5. **多个服务器如何配置不同的 `dataLevel`?**
|
|
@@ -637,7 +673,7 @@ export const apiUserListGet = (params: ApiUserList_GET.Query) => GET<ApiUserList
|
|
|
637
673
|
```json
|
|
638
674
|
{
|
|
639
675
|
"dataLevel": "serve",
|
|
640
|
-
"
|
|
676
|
+
"swaggerConfig": [
|
|
641
677
|
{
|
|
642
678
|
"url": "http://old-api.com/swagger.json",
|
|
643
679
|
"dataLevel": "axios",
|
|
@@ -654,11 +690,41 @@ export const apiUserListGet = (params: ApiUserList_GET.Query) => GET<ApiUserList
|
|
|
654
690
|
- `old-api.ts` 使用 `dataLevel: "axios"`
|
|
655
691
|
- `new-api.ts` 使用全局的 `dataLevel: "serve"`
|
|
656
692
|
|
|
657
|
-
6.
|
|
693
|
+
6. **如何为单个接口配置不同的 `dataLevel`?**
|
|
694
|
+
|
|
695
|
+
```json
|
|
696
|
+
{
|
|
697
|
+
"dataLevel": "serve",
|
|
698
|
+
"swaggerConfig": [
|
|
699
|
+
{
|
|
700
|
+
"url": "http://api.com/swagger.json",
|
|
701
|
+
"apiListFileName": "api.ts",
|
|
702
|
+
"dataLevel": "data",
|
|
703
|
+
"includeInterface": [
|
|
704
|
+
{
|
|
705
|
+
"path": "/api/user/detail",
|
|
706
|
+
"method": "get",
|
|
707
|
+
"dataLevel": "axios"
|
|
708
|
+
},
|
|
709
|
+
{
|
|
710
|
+
"path": "/api/user/list",
|
|
711
|
+
"method": "get"
|
|
712
|
+
}
|
|
713
|
+
]
|
|
714
|
+
}
|
|
715
|
+
]
|
|
716
|
+
}
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
- `/api/user/detail` 使用接口级别的 `dataLevel: "axios"`(最高优先级)
|
|
720
|
+
- `/api/user/list` 使用服务器级别的 `dataLevel: "data"`
|
|
721
|
+
- 其他服务器的接口使用全局的 `dataLevel: "serve"`
|
|
722
|
+
|
|
723
|
+
7. **如何只生成部分接口?**
|
|
658
724
|
- 使用 `includeInterface` 配置:
|
|
659
725
|
```json
|
|
660
726
|
{
|
|
661
|
-
"
|
|
727
|
+
"swaggerConfig": [
|
|
662
728
|
{
|
|
663
729
|
"url": "http://api.com/swagger.json",
|
|
664
730
|
"includeInterface": [
|
|
@@ -671,7 +737,7 @@ export const apiUserListGet = (params: ApiUserList_GET.Query) => GET<ApiUserList
|
|
|
671
737
|
```
|
|
672
738
|
- 或使用 `excludeInterface` 排除不需要的接口
|
|
673
739
|
|
|
674
|
-
|
|
740
|
+
8. **生成的文件被覆盖了怎么办?**
|
|
675
741
|
- `config.ts`、`error-message.ts`、`fetch.ts`、`api-type.d.ts` 这些文件只会在首次不存在时生成
|
|
676
742
|
- API 列表文件和类型文件每次都会重新生成
|
|
677
743
|
- 建议将生成的文件纳入版本控制,便于查看变更
|
package/lib/package.json.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e="26.107.
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e="26.107.1",i="FE command line tool",t="bin/an-cli.js",s={registry:"https://registry.npmjs.org"},o={dev:"rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript -w",build:"rimraf lib && rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript",pub:"bash publish.sh",ts:"tsc ./src/int.ts --noEmit --watch",blink:"npm run build && npm link","sync-docs":"node scripts/sync-docs.js"},r={anl:"bin/an-cli.js"},n="Gleason <bianliuzhu@gmail.com>",l={"@commitlint/cli":"^17.4.3","@commitlint/config-conventional":"^17.4.3","@rollup/plugin-commonjs":"^21.0.1","@rollup/plugin-json":"^4.1.0","@rollup/plugin-node-resolve":"^13.1.3","@rollup/plugin-typescript":"^8.3.0","@types/inquirer":"^9.0.7","@types/shelljs":"^0.8.11","@typescript-eslint/eslint-plugin":"^5.52.0","@typescript-eslint/parser":"^5.52.0","cross-env":"^7.0.3",eslint:"^8.7.0",husky:"^8.0.3","openapi-types":"^12.1.3",prettier:"^3.3.2",rimraf:"^5.0.7",rollup:"^2.64.0","rollup-plugin-cleandir":"^2.0.0","rollup-plugin-copy":"^3.5.0","rollup-plugin-terser":"^7.0.2",typescript:"^4.5.4"},p={"app-root-path":"^3.1.0",cac:"^6.7.12",chalk:"4.*","clear-console":"^1.1.0",commander:"14.0.1",figures:"^6.1.0",inquirer:"^10.1.8","log-symbols":"^5.1.0",ora:"5.*","progress-estimator":"^0.3.0",shelljs:"^0.8.5"},c=["cli","command-line","frontend","typescript","type-generation","code-generator","swagger","openapi","api","rest-api","eslint","stylelint","prettier","commitlint","linter","formatter","react","vue","git","gitflow","developer-tools","automation","scaffolding"],a=["package.json","README.md","lib","template"],u={type:"git",url:"git+https://github.com/bianliuzhu/an-cli.git"},g="commonjs",m={name:"anl",version:e,description:i,main:t,publishConfig:s,scripts:o,bin:r,author:n,license:"ISC",devDependencies:l,dependencies:p,keywords:c,files:a,repository:u,type:g};exports.author=n,exports.bin=r,exports.default=m,exports.dependencies=p,exports.description=i,exports.devDependencies=l,exports.files=a,exports.keywords=c,exports.license="ISC",exports.main=t,exports.name="anl",exports.publishConfig=s,exports.repository=u,exports.scripts=o,exports.type=g,exports.version=e;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("http"),r=require("https"),t=require("path"),o=require("../tools/index.js");function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=s(e),u=s(r),c=s(t);function a({swaggerJsonUrl:e="",headers:r={}}){return new Promise((t,o)=>{let s;const c=/^https/.test(e)?u.default.request:n.default.request;console.info(`Request Start: ${e}`);const a=c(e,{method:"GET",rejectUnauthorized:!1,headers:{Accept:"*/*","Accept-Encoding":"utf-8","Content-Type":"application/x-www-form-urlencoded",...r}},r=>{r.setEncoding("utf-8");let n="";r.on("data",e=>{n+=e.toString()}),r.on("end",()=>{clearTimeout(s);try{const r=JSON.parse(n);console.info(`Request Successful: ${e}`),t(r)}catch(r){console.error(`Request Failed: ${e}`,!0),o(r)}}),r.on("error",r=>{console.error(`Request Failed: ${e}`,!0),o(r)})});a.on("timeout",e=>{console.error(e,!0),o(e)}),s=setTimeout(()=>{const r=new Error;r.name="Request Timeout",r.message=e,a.emit("timeout",r)},15e3),a.end()})}exports.getSwaggerJson=async function(e){if(!e.swaggerJsonUrl)return Promise.reject(new Error("swaggerJsonUrl 未配置,请检查
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("http"),r=require("https"),t=require("path"),o=require("../tools/index.js");function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=s(e),u=s(r),c=s(t);function a({swaggerJsonUrl:e="",headers:r={}}){return new Promise((t,o)=>{let s;const c=/^https/.test(e)?u.default.request:n.default.request;console.info(`Request Start: ${e}`);const a=c(e,{method:"GET",rejectUnauthorized:!1,headers:{Accept:"*/*","Accept-Encoding":"utf-8","Content-Type":"application/x-www-form-urlencoded",...r}},r=>{r.setEncoding("utf-8");let n="";r.on("data",e=>{n+=e.toString()}),r.on("end",()=>{clearTimeout(s);try{const r=JSON.parse(n);console.info(`Request Successful: ${e}`),t(r)}catch(r){console.error(`Request Failed: ${e}`,!0),o(r)}}),r.on("error",r=>{console.error(`Request Failed: ${e}`,!0),o(r)})});a.on("timeout",e=>{console.error(e,!0),o(e)}),s=setTimeout(()=>{const r=new Error;r.name="Request Timeout",r.message=e,a.emit("timeout",r)},15e3),a.end()})}exports.getSwaggerJson=async function(e){if(!e.swaggerJsonUrl)return Promise.reject(new Error("swaggerJsonUrl 未配置,请检查 swaggerConfig.url"));if(/^https?:\/\//.test(e.swaggerJsonUrl))return a(e);try{const r=c.default.isAbsolute(e.swaggerJsonUrl)?e.swaggerJsonUrl:c.default.resolve(process.cwd(),e.swaggerJsonUrl),t=o.requireModule(r);return Promise.resolve(t)}catch(e){return console.error(e,!0),Promise.reject(e)}},exports.requestJson=a;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../../utils/index.js");const t="\t";var n;!function(e){e.GET="get",e.PUT="put",e.POST="post",e.DELETE="delete",e.OPTIONS="options",e.HEAD="head",e.PATCH="patch",e.TRACE="trace"}(n||(n={}));const r={typeMapping:new Map([["integer","number"],["string","string"],["boolean","boolean"],["binary","File"],["number","number"],["null","null"],["undefined","undefined"],["date","Date"],["time","Date"],["datetime","Date"],["timestamp","Date"]]),errorHandling:{throwOnError:!1,logErrors:!0}},s="#/components/schemas/",a="#/components/parameters/",i="#/definitions/",o=["application/json","text/json","text/plain","application/x-www-form-urlencoded","application/xml","text/xml","*/*","application/octet-stream","multipart/form-data"],c=["application/octet-stream","multipart/form-data"];class p{pathsObject={};nonArrayType=["boolean","object","number","string","integer"];pathKey="";contentBody={payload:{path:[],query:[],body:[]},response:"",_response:"",fileName:"",method:"",requestPath:"",summary:"",apiName:"",typeName:"",deprecated:!1,contentType:"application/json"};Map=new Map;config;errors=[];referenceCache=new Map;parameters={};schemas={};templates={exportConst:e=>`export const ${e}`,typeDefinition:(e,t)=>`type ${e} = ${t}`,interfaceDefinition:e=>`interface ${e}`};constructor(e,t,n,s){this.pathsObject=e,this.parameters=t??{},this.schemas=n??{},this.config={...r,...s,typeMapping:new Map([...r.typeMapping||[],...s.typeMapping||[]])}}handleError(t){if(this.errors.push(t),this.config.errorHandling?.logErrors&&e.log.error(`${t.type}: ${t.message}${t.path?` at ${t.path}`:""}`),this.config.errorHandling?.throwOnError)throw new Error(`${t.type}: ${t.message}`)}getIndentation(){return this.config.formatting?.indentation||t}getEnumTypeName(e){return this.config.enmuConfig.erasableSyntaxOnly?`${e}Type`:e}typeNameToFileName(e){return e=(e=(e=e.replace(/_/g,"-")).replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()).replace(/-+/g,"-")}stringifySchemaResult(e){if(Array.isArray(e)){const t=this.config.formatting?.lineEnding??"\n",n=this.getIndentation();return`{${t}${e.join(t)}${t}${n}}`}return e}handleComplexType(e){try{return e.oneOf?e.oneOf.map(e=>this.stringifySchemaResult(this.schemaParse(e))).join(" | "):e.allOf?e.allOf.map(e=>this.stringifySchemaResult(this.schemaParse(e))).join(" & "):e.anyOf?e.anyOf.map(e=>this.stringifySchemaResult(this.schemaParse(e))).join(" | "):e.enum?"number"===e.type||"integer"===e.type?e.enum.join(" | "):e.enum.map(e=>`'${e}'`).join(" | "):"unknown"}catch(e){return this.handleError({type:"SCHEMA",message:"Failed to handle complex type",details:e}),"unknown"}}propertiesParse(e){if(!e)return[];const n=[];for(const r in e){const s=e[r],a=this.schemaParse(s);let i="";i=Array.isArray(a)?`${t}${t}${r}: {${a.join("\n")}};`:`${t}${t}${r}: ${a};`,n.push(i)}return n}nonArraySchemaObjectParse(e){if(!e)return"unknown";if("binary"===e.format||"string"===e.type&&"binary"===e.format)return"File";switch(e.type){case"boolean":return"boolean";case"integer":case"number":return"number";case"object":return this.propertiesParse(e.properties);case"string":return"binary"===e.format?"File":"string";default:return"unknown"}}arraySchemaObjectParse(e){if("array"!==e.type)return"";const{items:t}=e,n="$ref"in t?t:null,r=t;if(n){return`Array<${this.referenceObjectParse(n)}>`}if(r){const e=this.schemaParse(t);return Array.isArray(e)?`Array<{${e.join("\n")}}>`:`Array<${e}>`}return""}referenceObjectParse(e){try{const t=e.$ref,n=this.referenceCache.get(t);if(n)return n;let r=t;t.startsWith(s)&&(r=t.replace(s,"")),t.startsWith(a)&&(r=t.replace(a,"")),t.startsWith(i)&&(r=t.replace(i,""));const o=this.typeNameToFileName(r),c=/enum/gi.test(r),p=this.schemas?.[r],l=p&&"enum"in p&&Array.isArray(p.enum),h=c||l,m=h?this.getEnumTypeName(r):r,y=h?`import('${this.config.importEnumPath}/${o}').${m}`:`import('../models/${o}').${r}`;return this.referenceCache.set(t,y),y}catch(e){return this.handleError({type:"REFERENCE",message:"Failed to parse reference object",details:e}),"unknown"}}schemaParse(e){try{if(!e)return"unknown";if("oneOf"in e||"allOf"in e||"anyOf"in e||"enum"in e)return this.handleComplexType(e);if("$ref"in e)return this.referenceObjectParse(e);const t=e,n=t.type,r=!0===t.nullable?" | null":"";if(e.format&&this.config.typeMapping?.has(e.format))return this.config.typeMapping.get(e.format)+r;if(n&&this.config.typeMapping?.has(n))return this.config.typeMapping.get(n)+r;if("array"===n&&t.items){const e=this.schemaParse(t.items);if(Array.isArray(e)){const t=this.config.formatting?.lineEnding,n=this.config.formatting?.indentation;return`Array<{${t}${e.join("\n")}${t}${n}${n}}>`}return`Array<${e}>`}if("object"===n||"object"==typeof t){if(t.properties){const e=this.propertiesParse(t.properties);return e.length?e:["unknown"]}if(!0===t.additionalProperties)return"Record<string, unknown>"+r;if("object"==typeof t.additionalProperties){return`Record<string, ${this.schemaParse(t.additionalProperties)}>`+r}}return"unknown"}catch(e){return this.handleError({type:"SCHEMA",message:"Failed to parse schema",details:e}),"unknown"}}responseObjectParse(e){try{const t=e.content;if(!t)return"";let n;for(const e of o)if(t[e]?.schema){n=t[e].schema;break}return n?this.schemaParse(n):""}catch(e){return this.handleError({type:"RESPONSE",message:"Failed to parse response object",details:e}),""}}responseHandle(e){const t=e[200];if(!t)return;const n="content"in t?t:null,r="$ref"in t?t:null;if(null===n&&null===r&&(this.contentBody.response="type Response = unknown",this.contentBody._response="unknown"),r){const e=this.referenceObjectParse(r);this.contentBody.response=`type Response = ${e}`,this.contentBody._response=e}if(n){const e=this.responseObjectParse(n);if(Array.isArray(e)){if(1===e.length&&"unknown"===e[0])this.contentBody.response=`type Response = ${e.join("\n")};`;else{const t=this.config.formatting?.lineEnding,n=this.config.formatting?.indentation;this.contentBody.response=`interface Response {${t}${e.join("\n")}${t}${n}};`}this.contentBody._response=`${e.join("\n")}`}else this.contentBody.response=`type Response = ${e}`,this.contentBody._response=`${e}`}}requestBodyObjectParse(e){const n=Object.values(e.content),{schema:r}=n[0]||{schema:null};if(r){const e=r?.type,n="$ref"in r?r:null,s="array"===e?r:null,a=e&&this.nonArrayType.includes(e)?r:null;if(n){const e=this.referenceObjectParse(n);return`${t}type Body = ${e}`}if(s){const e=this.arraySchemaObjectParse(s);return`${t}type Body = ${e}`}if(a){const e=this.nonArraySchemaObjectParse(a);return Array.isArray(e)?0===e.length?[`${t}type Body = ${a.type};`]:[`${t}interface Body {`,...e.map(e=>e.replace(/: string;/,": File;")),"}"]:[`${t}type Body = ${e}`]}}}requestBodyParse(e){if(!e)return"{}";const n="$ref"in e?e:null,r="content"in e?e:null;if(n){const e=this.referenceObjectParse(n);return`${t}type Body = ${e}`}return r&&"[object Object]"===String(e)&&0!==Reflect.ownKeys(e).length?this.requestBodyObjectParse(r):"{}"}parametersItemHandle(e,n,r){const s="$ref"in e?e:null,i="name"in e?e:null;if(s&&s.$ref&&s.$ref.startsWith(a)&&this.parameters){const e=s.$ref.replace(a,""),t=this.parameters[e];this.parametersItemHandle(t,n,r)}if(i){if("path"===i.in){const e=this.schemaParse(i.schema);n.push(`${t}${t}type ${i.name} = ${e};`),this.contentBody.payload._path?"string"==typeof e?this.contentBody.payload._path[i.name]=e:console.log("Unexpected v2value type:",e):"string"==typeof e?this.contentBody.payload._path={[i.name]:e}:console.log("Unexpected v2value type:",e)}if("query"===i.in){const e=this.schemaParse(i.schema);r.push(`${t}${t}${i.name}: ${e};`),this.contentBody.payload._query?"string"==typeof e?this.contentBody.payload._query[i.name]=e:console.log("Unexpected v2value type:",e):"string"==typeof e?this.contentBody.payload._query={[i.name]:e}:console.log("Unexpected v2value type:",e)}}}requestParametersParse(e){const n=[],r=[];e?.map(e=>this.parametersItemHandle(e,n,r)),0!==n.length&&(n.unshift(`${t}namespace Path {`),n.push(`${t}}`)),0!==r.length&&(r.unshift(`${t}interface Query {`),r.push(`${t}}`)),this.contentBody.payload.path=n,this.contentBody.payload.query=r}requestHandle(e){if(e.parameters&&this.requestParametersParse(e.parameters),e.requestBody){const t=this.requestBodyParse(e.requestBody);if(Array.isArray(t))this.contentBody.payload.body=t;else if(t){const e=t?.split("\n")||[];this.contentBody.payload.body=e}}}normalizemodulePrefix(e){if(!e||""===e.trim())return"";let t=e.trim();return t=t.replace(/\/+$/g,""),t.startsWith("/")||(t="/"+t),t}apiRequestItemHandle(e){const{payload:t,requestPath:n,_response:r,method:s,typeName:a,apiName:i,contentType:o}=e,{_path:p,_query:l,body:h}=t,m=this.config.dataLevel||"serve",y=this.normalizemodulePrefix(this.config.modulePrefix),u=(()=>{const e=[];for(const t in p)e.push(`${t}: ${a}.Path.${t}`);const t=e.join(e.length>1?",":"");return""===t?t:t+","})(),d=(()=>{const e=l?`query: ${a}.Query,`:"";return""===e?"":`${e}`})(),f=(()=>{const e=h.length>0?`body: ${a}.Body,`:"";return""===e?"":`${e}`})(),g=(u+d+f).replace(/,$/,"");return[`export const ${i} = `,"(",g,""===g?"params?: IRequestFnParams":", params?: IRequestFnParams",")"," => ",s,""+(r?`<${a}.Response>`:""),"(",`\`${y}${n}\`,`,(()=>{const e=c.includes(o)?`headers: { 'Content-Type': '${o}' }`:void 0;return["{",e?`${e},`:"","...params, ",""===d?"":"query,",""===f?"":"body,","},"].join("")})(),`'${m}'`,");"].join("")}parsePathItemObject(e,t){if(e)for(const n in e){const r=e[n];if(r){if(this.config.includeInterface&&this.config.includeInterface.length>0){const e=this.config.includeInterface?.find(e=>t.includes(e.path)&&e.method===n);if(!e)return}else if(this.config.excludeInterface&&this.config.excludeInterface.length>0){const e=this.config.excludeInterface?.find(e=>t.includes(e.path)&&e.method===n);if(e)return}const e=n.toUpperCase(),s=t+"|"+e,{apiName:a,typeName:i,fileName:c,path:p}=this.convertEndpointString(s),l=r.requestBody&&"content"in r.requestBody&&r.requestBody.content,h="object"==typeof l?Object.keys(l)[0]:"application/json";this.contentBody={payload:{path:[],query:[],body:[]},response:"",_response:"",fileName:c,method:e,typeName:i,requestPath:p,apiName:a,summary:r.summary,deprecated:r.deprecated??!1,contentType:o.includes(h)?h:"application/json"},this.requestHandle(r),this.responseHandle(r.responses),this.Map.has(s)||this.Map.set(s,JSON.parse(JSON.stringify(this.contentBody)))}}}cleanSegment(e){let t=e.replace(/^[0-9]+/,"");return t?(t=t.replace(/[^a-zA-Z0-9_.-]/g,""),t):"num"+e}toCamelCase(e,t=!1){const n=this.cleanSegment(e).split(/[-_.]+/).filter(e=>e.length>0);return 0===n.length?"":n.map((e,n)=>0===n&&t?e.toLowerCase():e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")}toPascalCase(e){const t=this.cleanSegment(e).split(/[-_.]+/).filter(e=>e.length>0);return 0===t.length?"":t.map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")}convertEndpointString(e){let t=e;e.startsWith("/")||(t="/"+e);const[n,r]=t.split("|");let s="";this.config.publicPrefix&&(s=this.config.publicPrefix.replace(/^\/+|\/+$/g,""));let a=n.replace(/^\/+/,"");if(s&&a.startsWith(s+"/"))a=a.slice(s.length+1);else if(s&&a===s)a="";else if(s&&a.startsWith(s)){const e=a.slice(s.length);(e.startsWith("/")||""===e)&&(a=e.replace(/^\/+/,""))}const i=a?a.split("/").filter(e=>e):[],o=i.map(e=>{if(e.startsWith("{")&&e.endsWith("}")){const t=e.slice(1,-1);return{type:"param",original:e,normalized:t}}return{type:"normal",original:e,normalized:e}}),c=[];for(let e=0;e<o.length;e++){const t=o[e],n=o[e+1];if("normal"===t.type&&n&&"param"===n.type){if(this.cleanSegment(t.normalized).toLowerCase().replace(/[-_.]/g,"")===this.cleanSegment(n.normalized).toLowerCase().replace(/[-_.]/g,""))continue}c.push(t)}const p=this.config.parameterSeparator||"_";let l="",h=[];const m=e=>{if(h.length>0){const t=h.map((t,n)=>this.toCamelCase(t,e&&0===n)).join("");l+=(l&&h.length>0?p:"")+t,h=[]}};for(let e=0;e<c.length;e++){const t=c[e];if("normal"===t.type)h.push(t.normalized);else{m(""===l);const e=this.cleanSegment(t.normalized);l+=(l?p:"")+e}}m(""===l);let y="";h=[];const u=()=>{if(h.length>0){const e=h.map(e=>this.toPascalCase(e)).join("");y+=(y&&h.length>0?p:"")+e,h=[]}};for(let e=0;e<c.length;e++){const t=c[e];if("normal"===t.type)h.push(t.normalized);else{u();const e=this.toPascalCase(t.normalized);y+=(y?p:"")+e}}u();let d="";i.length>0?(d=i.map(e=>e.replace(/[{}]/g,"")).join("-"),d=`${d}-${r}`.toLowerCase()):d=`${r}`.toLowerCase();let f="/"+a;a||(f="/"),f=f.replace(/\{(\w+)\}/g,(e,t)=>`\${${t}}`);return{apiName:l?`${l}_${r}`:r,fileName:d,typeName:y?`${y}_${r}`:r,path:f}}parseData(){return new Promise((e,t)=>{try{for(const e in this.pathsObject){const t=this.pathsObject[e];t&&this.parsePathItemObject(t,e)}e(this.Map)}catch(e){this.handleError({type:"SCHEMA",message:"Failed to parse schema",details:e}),t(e)}})}async writeFile(){const n=[],r=[],s=this.config.saveTypeFolderPath,a=[],i=(n,i)=>new Promise((o,c)=>{try{const{payload:p,response:l,fileName:h,summary:m,typeName:y,deprecated:u}=i,[,d]=n.split("|");!a.includes(d)&&a.push(d);const f=[`declare namespace ${y} {`,...p.path,...p.query,...p.body,`${t}${l}`,"}"];m&&r.push(["/**","\n",u?` * @deprecated ${m}`:` * ${m}`,"\n"," */"].join(""));const g=this.apiRequestItemHandle(i);r.push(g,"");const $=`${s}/connectors/${h}.d.ts`;e.writeFileRecursive($,f.join("\n")).then(()=>{e.log.info(`${$.padEnd(80)} - Write done!`),o(1)}).catch(e=>{this.handleError({type:"FILE_WRITE",message:"Failed to write type definition file",path:h,details:e}),c(e)})}catch(e){this.handleError({type:"PATH",message:"Failed to process path item",path:n,details:e}),c(e)}});for(const[e,t]of this.Map)n.push(i(e,t));try{await Promise.all(n),e.log.success("Path parse & write done!"),r.unshift(`import { ${a.join(", ")} } from '${this.config.requestMethodsImportPath||"./api"}';`,"\n");const t=this.config.apiListFileName||"index.ts",s=`${this.config.saveApiListFolderPath}/${t}`;await e.clearDir(s),await e.writeFileRecursive(s,r.join("\n")),this.Map=new Map,this.errors.length>0&&e.log.warning(`Completed with ${this.errors.length} errors`)}catch(e){throw this.handleError({type:"FILE_WRITE",message:"Failed to write API list file",details:e}),e}}async handle(){try{await this.parseData(),await this.writeFile()}catch(e){if(this.handleError({type:"SCHEMA",message:"Failed to handle schema",details:e}),this.config.errorHandling?.throwOnError)throw e}}}exports.PathParse=p,exports.default=p;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../../utils/index.js");const t="\t";var n;!function(e){e.GET="get",e.PUT="put",e.POST="post",e.DELETE="delete",e.OPTIONS="options",e.HEAD="head",e.PATCH="patch",e.TRACE="trace"}(n||(n={}));const r={typeMapping:new Map([["integer","number"],["string","string"],["boolean","boolean"],["binary","File"],["number","number"],["null","null"],["undefined","undefined"],["date","Date"],["time","Date"],["datetime","Date"],["timestamp","Date"]]),errorHandling:{throwOnError:!1,logErrors:!0}},s="#/components/schemas/",a="#/components/parameters/",i="#/definitions/",o=["application/json","text/json","text/plain","application/x-www-form-urlencoded","application/xml","text/xml","*/*","application/octet-stream","multipart/form-data"],c=["application/octet-stream","multipart/form-data"];class p{pathsObject={};nonArrayType=["boolean","object","number","string","integer"];pathKey="";contentBody={payload:{path:[],query:[],body:[]},response:"",_response:"",fileName:"",method:"",requestPath:"",summary:"",apiName:"",typeName:"",deprecated:!1,contentType:"application/json"};Map=new Map;config;errors=[];referenceCache=new Map;parameters={};schemas={};templates={exportConst:e=>`export const ${e}`,typeDefinition:(e,t)=>`type ${e} = ${t}`,interfaceDefinition:e=>`interface ${e}`};constructor(e,t,n,s){this.pathsObject=e,this.parameters=t??{},this.schemas=n??{},this.config={...r,...s,typeMapping:new Map([...r.typeMapping||[],...s.typeMapping||[]])}}handleError(t){if(this.errors.push(t),this.config.errorHandling?.logErrors&&e.log.error(`${t.type}: ${t.message}${t.path?` at ${t.path}`:""}`),this.config.errorHandling?.throwOnError)throw new Error(`${t.type}: ${t.message}`)}getIndentation(){return this.config.formatting?.indentation||t}getEnumTypeName(e){return this.config.enmuConfig.erasableSyntaxOnly?`${e}Type`:e}typeNameToFileName(e){return e=(e=(e=e.replace(/_/g,"-")).replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()).replace(/-+/g,"-")}stringifySchemaResult(e){if(Array.isArray(e)){const t=this.config.formatting?.lineEnding??"\n",n=this.getIndentation();return`{${t}${e.join(t)}${t}${n}}`}return e}handleComplexType(e){try{return e.oneOf?e.oneOf.map(e=>this.stringifySchemaResult(this.schemaParse(e))).join(" | "):e.allOf?e.allOf.map(e=>this.stringifySchemaResult(this.schemaParse(e))).join(" & "):e.anyOf?e.anyOf.map(e=>this.stringifySchemaResult(this.schemaParse(e))).join(" | "):e.enum?"number"===e.type||"integer"===e.type?e.enum.join(" | "):e.enum.map(e=>`'${e}'`).join(" | "):"unknown"}catch(e){return this.handleError({type:"SCHEMA",message:"Failed to handle complex type",details:e}),"unknown"}}propertiesParse(e){if(!e)return[];const n=[];for(const r in e){const s=e[r],a=this.schemaParse(s);let i="";i=Array.isArray(a)?`${t}${t}${r}: {${a.join("\n")}};`:`${t}${t}${r}: ${a};`,n.push(i)}return n}nonArraySchemaObjectParse(e){if(!e)return"unknown";if("binary"===e.format||"string"===e.type&&"binary"===e.format)return"File";switch(e.type){case"boolean":return"boolean";case"integer":case"number":return"number";case"object":return this.propertiesParse(e.properties);case"string":return"binary"===e.format?"File":"string";default:return"unknown"}}arraySchemaObjectParse(e){if("array"!==e.type)return"";const{items:t}=e,n="$ref"in t?t:null,r=t;if(n){return`Array<${this.referenceObjectParse(n)}>`}if(r){const e=this.schemaParse(t);return Array.isArray(e)?`Array<{${e.join("\n")}}>`:`Array<${e}>`}return""}referenceObjectParse(e){try{const t=e.$ref,n=this.referenceCache.get(t);if(n)return n;let r=t;t.startsWith(s)&&(r=t.replace(s,"")),t.startsWith(a)&&(r=t.replace(a,"")),t.startsWith(i)&&(r=t.replace(i,""));const o=this.typeNameToFileName(r),c=/enum/gi.test(r),p=this.schemas?.[r],l=p&&"enum"in p&&Array.isArray(p.enum),h=c||l,m=h?this.getEnumTypeName(r):r,y=h?`import('${this.config.importEnumPath}/${o}').${m}`:`import('../models/${o}').${r}`;return this.referenceCache.set(t,y),y}catch(e){return this.handleError({type:"REFERENCE",message:"Failed to parse reference object",details:e}),"unknown"}}schemaParse(e){try{if(!e)return"unknown";if("oneOf"in e||"allOf"in e||"anyOf"in e||"enum"in e)return this.handleComplexType(e);if("$ref"in e)return this.referenceObjectParse(e);const t=e,n=t.type,r=!0===t.nullable?" | null":"";if(e.format&&this.config.typeMapping?.has(e.format))return this.config.typeMapping.get(e.format)+r;if(n&&this.config.typeMapping?.has(n))return this.config.typeMapping.get(n)+r;if("array"===n&&t.items){const e=this.schemaParse(t.items);if(Array.isArray(e)){const t=this.config.formatting?.lineEnding,n=this.config.formatting?.indentation;return`Array<{${t}${e.join("\n")}${t}${n}${n}}>`}return`Array<${e}>`}if("object"===n||"object"==typeof t){if(t.properties){const e=this.propertiesParse(t.properties);return e.length?e:["unknown"]}if(!0===t.additionalProperties)return"Record<string, unknown>"+r;if("object"==typeof t.additionalProperties){return`Record<string, ${this.schemaParse(t.additionalProperties)}>`+r}}return"unknown"}catch(e){return this.handleError({type:"SCHEMA",message:"Failed to parse schema",details:e}),"unknown"}}responseObjectParse(e){try{const t=e.content;if(!t)return"";let n;for(const e of o)if(t[e]?.schema){n=t[e].schema;break}return n?this.schemaParse(n):""}catch(e){return this.handleError({type:"RESPONSE",message:"Failed to parse response object",details:e}),""}}responseHandle(e){const t=e[200];if(!t)return;const n="content"in t?t:null,r="$ref"in t?t:null;if(null===n&&null===r&&(this.contentBody.response="type Response = unknown",this.contentBody._response="unknown"),r){const e=this.referenceObjectParse(r);this.contentBody.response=`type Response = ${e}`,this.contentBody._response=e}if(n){const e=this.responseObjectParse(n);if(Array.isArray(e)){if(1===e.length&&"unknown"===e[0])this.contentBody.response=`type Response = ${e.join("\n")};`;else{const t=this.config.formatting?.lineEnding,n=this.config.formatting?.indentation;this.contentBody.response=`interface Response {${t}${e.join("\n")}${t}${n}};`}this.contentBody._response=`${e.join("\n")}`}else this.contentBody.response=`type Response = ${e}`,this.contentBody._response=`${e}`}}requestBodyObjectParse(e){const n=Object.values(e.content),{schema:r}=n[0]||{schema:null};if(r){const e=r?.type,n="$ref"in r?r:null,s="array"===e?r:null,a=e&&this.nonArrayType.includes(e)?r:null;if(n){const e=this.referenceObjectParse(n);return`${t}type Body = ${e}`}if(s){const e=this.arraySchemaObjectParse(s);return`${t}type Body = ${e}`}if(a){const e=this.nonArraySchemaObjectParse(a);return Array.isArray(e)?0===e.length?[`${t}type Body = ${a.type};`]:[`${t}interface Body {`,...e.map(e=>e.replace(/: string;/,": File;")),"}"]:[`${t}type Body = ${e}`]}}}requestBodyParse(e){if(!e)return"{}";const n="$ref"in e?e:null,r="content"in e?e:null;if(n){const e=this.referenceObjectParse(n);return`${t}type Body = ${e}`}return r&&"[object Object]"===String(e)&&0!==Reflect.ownKeys(e).length?this.requestBodyObjectParse(r):"{}"}parametersItemHandle(e,n,r){const s="$ref"in e?e:null,i="name"in e?e:null;if(s&&s.$ref&&s.$ref.startsWith(a)&&this.parameters){const e=s.$ref.replace(a,""),t=this.parameters[e];this.parametersItemHandle(t,n,r)}if(i){if("path"===i.in){const e=this.schemaParse(i.schema);n.push(`${t}${t}type ${i.name} = ${e};`),this.contentBody.payload._path?"string"==typeof e?this.contentBody.payload._path[i.name]=e:console.log("Unexpected v2value type:",e):"string"==typeof e?this.contentBody.payload._path={[i.name]:e}:console.log("Unexpected v2value type:",e)}if("query"===i.in){const e=this.schemaParse(i.schema);r.push(`${t}${t}${i.name}: ${e};`),this.contentBody.payload._query?"string"==typeof e?this.contentBody.payload._query[i.name]=e:console.log("Unexpected v2value type:",e):"string"==typeof e?this.contentBody.payload._query={[i.name]:e}:console.log("Unexpected v2value type:",e)}}}requestParametersParse(e){const n=[],r=[];e?.map(e=>this.parametersItemHandle(e,n,r)),0!==n.length&&(n.unshift(`${t}namespace Path {`),n.push(`${t}}`)),0!==r.length&&(r.unshift(`${t}interface Query {`),r.push(`${t}}`)),this.contentBody.payload.path=n,this.contentBody.payload.query=r}requestHandle(e){if(e.parameters&&this.requestParametersParse(e.parameters),e.requestBody){const t=this.requestBodyParse(e.requestBody);if(Array.isArray(t))this.contentBody.payload.body=t;else if(t){const e=t?.split("\n")||[];this.contentBody.payload.body=e}}}normalizemodulePrefix(e){if(!e||""===e.trim())return"";let t=e.trim();return t=t.replace(/\/+$/g,""),t.startsWith("/")||(t="/"+t),t}apiRequestItemHandle(e){const{payload:t,requestPath:n,_response:r,method:s,typeName:a,apiName:i,contentType:o}=e,{_path:p,_query:l,body:h}=t,m=e.dataLevel||this.config.dataLevel||"serve",y=this.normalizemodulePrefix(this.config.modulePrefix),u=(()=>{const e=[];for(const t in p)e.push(`${t}: ${a}.Path.${t}`);const t=e.join(e.length>1?",":"");return""===t?t:t+","})(),d=(()=>{const e=l?`query: ${a}.Query,`:"";return""===e?"":`${e}`})(),f=(()=>{const e=h.length>0?`body: ${a}.Body,`:"";return""===e?"":`${e}`})(),g=(u+d+f).replace(/,$/,"");return[`export const ${i} = `,"(",g,""===g?"params?: IRequestFnParams":", params?: IRequestFnParams",")"," => ",s,""+(r?`<${a}.Response>`:""),"(",`\`${y}${n}\`,`,(()=>{const e=c.includes(o)?`headers: { 'Content-Type': '${o}' }`:void 0;return["{",e?`${e},`:"","...params, ",""===d?"":"query,",""===f?"":"body,","},"].join("")})(),`'${m}'`,");"].join("")}parsePathItemObject(e,t){if(e)for(const n in e){const r=e[n];if(r){let e;if(this.config.includeInterface&&this.config.includeInterface.length>0){const r=this.config.includeInterface?.find(e=>t.includes(e.path)&&e.method===n);if(!r)return;e=r}else if(this.config.excludeInterface&&this.config.excludeInterface.length>0){const e=this.config.excludeInterface?.find(e=>t.includes(e.path)&&e.method===n);if(e)return}const s=n.toUpperCase(),a=t+"|"+s,{apiName:i,typeName:c,fileName:p,path:l}=this.convertEndpointString(a),h=r.requestBody&&"content"in r.requestBody&&r.requestBody.content,m="object"==typeof h?Object.keys(h)[0]:"application/json";this.contentBody={payload:{path:[],query:[],body:[]},response:"",_response:"",fileName:p,method:s,typeName:c,requestPath:l,apiName:i,summary:r.summary,deprecated:r.deprecated??!1,contentType:o.includes(m)?m:"application/json",dataLevel:e?.dataLevel},this.requestHandle(r),this.responseHandle(r.responses),this.Map.has(a)||this.Map.set(a,JSON.parse(JSON.stringify(this.contentBody)))}}}cleanSegment(e){let t=e.replace(/^[0-9]+/,"");return t?(t=t.replace(/[^a-zA-Z0-9_.-]/g,""),t):"num"+e}toCamelCase(e,t=!1){const n=this.cleanSegment(e).split(/[-_.]+/).filter(e=>e.length>0);return 0===n.length?"":n.map((e,n)=>0===n&&t?e.toLowerCase():e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")}toPascalCase(e){const t=this.cleanSegment(e).split(/[-_.]+/).filter(e=>e.length>0);return 0===t.length?"":t.map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")}convertEndpointString(e){let t=e;e.startsWith("/")||(t="/"+e);const[n,r]=t.split("|");let s="";this.config.publicPrefix&&(s=this.config.publicPrefix.replace(/^\/+|\/+$/g,""));let a=n.replace(/^\/+/,"");if(s&&a.startsWith(s+"/"))a=a.slice(s.length+1);else if(s&&a===s)a="";else if(s&&a.startsWith(s)){const e=a.slice(s.length);(e.startsWith("/")||""===e)&&(a=e.replace(/^\/+/,""))}const i=a?a.split("/").filter(e=>e):[],o=i.map(e=>{if(e.startsWith("{")&&e.endsWith("}")){const t=e.slice(1,-1);return{type:"param",original:e,normalized:t}}return{type:"normal",original:e,normalized:e}}),c=[];for(let e=0;e<o.length;e++){const t=o[e],n=o[e+1];if("normal"===t.type&&n&&"param"===n.type){if(this.cleanSegment(t.normalized).toLowerCase().replace(/[-_.]/g,"")===this.cleanSegment(n.normalized).toLowerCase().replace(/[-_.]/g,""))continue}c.push(t)}const p=this.config.parameterSeparator||"_";let l="",h=[];const m=e=>{if(h.length>0){const t=h.map((t,n)=>this.toCamelCase(t,e&&0===n)).join("");l+=(l&&h.length>0?p:"")+t,h=[]}};for(let e=0;e<c.length;e++){const t=c[e];if("normal"===t.type)h.push(t.normalized);else{m(""===l);const e=this.cleanSegment(t.normalized);l+=(l?p:"")+e}}m(""===l);let y="";h=[];const u=()=>{if(h.length>0){const e=h.map(e=>this.toPascalCase(e)).join("");y+=(y&&h.length>0?p:"")+e,h=[]}};for(let e=0;e<c.length;e++){const t=c[e];if("normal"===t.type)h.push(t.normalized);else{u();const e=this.toPascalCase(t.normalized);y+=(y?p:"")+e}}u();let d="";i.length>0?(d=i.map(e=>e.replace(/[{}]/g,"")).join("-"),d=`${d}-${r}`.toLowerCase()):d=`${r}`.toLowerCase();let f="/"+a;a||(f="/"),f=f.replace(/\{(\w+)\}/g,(e,t)=>`\${${t}}`);return{apiName:l?`${l}_${r}`:r,fileName:d,typeName:y?`${y}_${r}`:r,path:f}}parseData(){return new Promise((e,t)=>{try{for(const e in this.pathsObject){const t=this.pathsObject[e];t&&this.parsePathItemObject(t,e)}e(this.Map)}catch(e){this.handleError({type:"SCHEMA",message:"Failed to parse schema",details:e}),t(e)}})}async writeFile(){const n=[],r=[],s=this.config.saveTypeFolderPath,a=[],i=(n,i)=>new Promise((o,c)=>{try{const{payload:p,response:l,fileName:h,summary:m,typeName:y,deprecated:u}=i,[,d]=n.split("|");!a.includes(d)&&a.push(d);const f=[`declare namespace ${y} {`,...p.path,...p.query,...p.body,`${t}${l}`,"}"];m&&r.push(["/**","\n",u?` * @deprecated ${m}`:` * ${m}`,"\n"," */"].join(""));const g=this.apiRequestItemHandle(i);r.push(g,"");const $=`${s}/connectors/${h}.d.ts`;e.writeFileRecursive($,f.join("\n")).then(()=>{e.log.info(`${$.padEnd(80)} - Write done!`),o(1)}).catch(e=>{this.handleError({type:"FILE_WRITE",message:"Failed to write type definition file",path:h,details:e}),c(e)})}catch(e){this.handleError({type:"PATH",message:"Failed to process path item",path:n,details:e}),c(e)}});for(const[e,t]of this.Map)n.push(i(e,t));try{await Promise.all(n),e.log.success("Path parse & write done!"),r.unshift(`import { ${a.join(", ")} } from '${this.config.requestMethodsImportPath||"./api"}';`,"\n");const t=this.config.apiListFileName||"index.ts",s=`${this.config.saveApiListFolderPath}/${t}`;await e.clearDir(s),await e.writeFileRecursive(s,r.join("\n")),this.Map=new Map,this.errors.length>0&&e.log.warning(`Completed with ${this.errors.length} errors`)}catch(e){throw this.handleError({type:"FILE_WRITE",message:"Failed to write API list file",details:e}),e}}async handle(){try{await this.parseData(),await this.writeFile()}catch(e){if(this.handleError({type:"SCHEMA",message:"Failed to handle schema",details:e}),this.config.errorHandling?.throwOnError)throw e}}}exports.PathParse=p,exports.default=p;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("fs"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("fs"),a=require("../utils/index.js"),r=require("./core/components.js"),s=require("./core/get-data.js"),t=require("./core/path.js"),i=require("shelljs"),o=require("chalk"),n=require("path");function l(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var c=l(e),g=l(o),u=l(n);let d;const f="debug"===process.env.NODE_ENV,p={saveTypeFolderPath:f?"apps/types":"src/api/types",saveApiListFolderPath:f?"apps/types":"src/api",saveEnumFolderPath:f?"apps/types/enums":"src/enums",importEnumPath:"../../../enums",requestMethodsImportPath:"./fetch",formatting:{indentation:"\t",lineEnding:"\n"},swaggerConfig:{url:"https://generator3.swagger.io/openapi.json",apiListFileName:"index.ts",headers:{},dataLevel:"serve",parameterSeparator:"_",includeInterface:[],excludeInterface:[]},enmuConfig:{erasableSyntaxOnly:!1,varnames:"enum-varnames",comment:"enum-descriptions"}};class h{schemas={};paths={};async handle(e,a){try{const i=await s.getSwaggerJson(e);if(!i)throw new Error("无法获取 Swagger 数据");this.schemas=i.components?.schemas||{},this.paths=i.paths||{};const o=new r.default(this.schemas,e,{appendMode:a}),n=new t.PathParse(this.paths,i.components?.parameters,this.schemas,e);return await o.handle(),await n.handle(),!0}catch(e){if(e instanceof Error)throw new Error(`Handle Swagger data failed: ${e.message}`);throw new Error("Handle Swagger data failed: unknown error")}}async formatGeneratedFiles(e){const r=`npx prettier --write "${e.saveTypeFolderPath}/**/*.{ts,d.ts}"`;try{await c.default.promises.access(e.saveTypeFolderPath);const{stderr:s}=await new Promise((e,a)=>{i.exec(r,(r,s,t)=>{r?a(r):e({stdout:s,stderr:t})})});s&&(console.log("\n"),console.log("$",g.default.yellow(r)),console.log("\n")),a.log.success("File formatting successful"),console.log("\n")}catch(e){console.log(""),console.log(e),a.log.error("Format failed, please manually execute the following command:"),console.log("$",g.default.yellow(r)),console.log("")}}async copyAjaxConfigFiles(e){try{const r=["config.ts","error-message.ts","fetch.ts","api-type.d.ts"],s=f?u.default.join(__dirname,"..","..","postbuild-assets","ajax-config"):u.default.join(__dirname,"..","..","ajax-config"),t=e;for(const e of r){const r=u.default.join(s,e),i=u.default.join(t,e);try{await c.default.promises.access(r);try{await c.default.promises.access(i),a.log.info(`${e} already exists, skipping generation.`)}catch{await c.default.promises.copyFile(r,i),a.log.success(`${e} create done.`)}}catch(e){a.log.error(`Source file ${r} does not exist`);continue}}}catch(e){return e}}getSystemLocale(){try{return Intl.DateTimeFormat().resolvedOptions().locale.toLowerCase()}catch{return(process.env.LANG||process.env.LC_ALL||process.env.LC_MESSAGES||"").toLowerCase()}}showLegacyConfigHint(e){const a={url:e.swaggerJsonUrl||"https://your.swagger.json",publicPrefix:e.publicPrefix||"",apiListFileName:e.apiListFileName||"index.ts",headers:e.headers||{}},r=this.getSystemLocale();r.startsWith("zh")||r.includes("chinese")?(console.log("\n检测到旧版配置,请更新 an.config.json:"),console.log("1) 将 swaggerJsonUrl / publicPrefix / headers 移到 swaggerConfig 字段。"),console.log("2) 单个服务可直接填写对象,多个服务请使用数组,并确保 apiListFileName 唯一。"),console.log("示例:"),console.log(JSON.stringify({swaggerConfig:a},null,2)),console.log("")):(console.log("\nLegacy configuration detected, please update an.config.json:"),console.log("1) Move swaggerJsonUrl / publicPrefix / headers to swaggerConfig field."),console.log("2) Single service can be an object directly, multiple services should use an array, and ensure apiListFileName is unique."),console.log("Example:"),console.log(JSON.stringify({swaggerConfig:a},null,2)),console.log(""))}normalizeswaggerConfig(e,a){let r=!1,s=a?e.swaggerConfig:void 0;s||(r=!0,s={url:e.swaggerJsonUrl||"",publicPrefix:e.publicPrefix||"",apiListFileName:e.apiListFileName||"index.ts",headers:e.headers||{},modulePrefix:e.modulePrefix});const t=(a,s)=>{const t=a.url||e.swaggerJsonUrl;if(!t)throw new Error(`swaggerConfig[${s}] 缺少 url,请补充后重试。`);const i=a.publicPrefix??e.publicPrefix??"";!a.url&&e.swaggerJsonUrl&&(r=!0);return{url:t,publicPrefix:i,apiListFileName:(a.apiListFileName||e.apiListFileName||"index.ts").trim()||"index.ts",headers:a.headers||e.headers||{},dataLevel:a.dataLevel||e.dataLevel||"serve",parameterSeparator:a.parameterSeparator||e.parameterSeparator||"_",includeInterface:a.includeInterface||e.includeInterface||[],excludeInterface:a.excludeInterface||e.excludeInterface||[],modulePrefix:a.modulePrefix??e.modulePrefix??""}},i=Array.isArray(s)?s.map((e,a)=>t(e,a)):[t(s,0)];if(0===i.length)throw new Error("swaggerConfig 不能为空,请至少配置一个 swagger 服务。");if(i.length>1){const e=new Set;i.forEach(a=>{if(e.has(a.apiListFileName))throw new Error(`swaggerConfig 中 apiListFileName 重复:${a.apiListFileName},请为每个服务设置唯一文件名。`);e.add(a.apiListFileName)})}return r&&this.showLegacyConfigHint(e),i}buildServerConfig(e,a){return{...e,swaggerJsonUrl:a.url,publicPrefix:a.publicPrefix??e.publicPrefix,headers:a.headers,apiListFileName:a.apiListFileName,dataLevel:a.dataLevel,parameterSeparator:a.parameterSeparator,includeInterface:a.includeInterface,excludeInterface:a.excludeInterface,modulePrefix:a.modulePrefix,swaggerConfig:a}}async getConfig(e){try{const a=await c.default.promises.readFile(e,"utf8");return d=!0,JSON.parse(a)}catch(r){return d=!1,a.log.warning("Config file does not exist, will automatically create config file."),await a.writeFileRecursive(e,JSON.stringify(p,null,2)),a.log.success("Please check the an.config.json file in the project root directory"),p}}async initialize(){const e=process.cwd()+"/an.config.json";try{const r=await this.getConfig(e),s={...p,...r},t=Object.prototype.hasOwnProperty.call(r,"swaggerConfig"),i=this.normalizeswaggerConfig(s,t);if(!d)return;await c.default.promises.mkdir(s.saveApiListFolderPath,{recursive:!0}),await this.copyAjaxConfigFiles(s.saveApiListFolderPath),await a.clearDir(s.saveTypeFolderPath),await a.clearDir(s.saveEnumFolderPath);for(let e=0;e<i.length;e++){const a=this.buildServerConfig(s,i[e]),r=e>0;await this.handle(a,r)}await this.formatGeneratedFiles(s),a.log.success("Successfully, all done, see you next time!"),console.log("\n")}catch(e){const r=e instanceof Error?e.message:"Unknown error";a.log.error(`Initialization failed: ${r}`)}}}if(f){(new h).initialize()}exports.Main=h;
|