Skip to content

Commit fc26318

Browse files
Merge pull request #612 from openapi-ui/feat/config-props-validate
perf: perf config props validate
2 parents 1a8f079 + 484e60b commit fc26318

9 files changed

Lines changed: 72 additions & 30 deletions

File tree

.changeset/wide-nails-mix.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'openapi-ts-request': patch
3+
---
4+
5+
perf: perf config props validate

README-en_US.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,8 @@ openapi -i ./spec.json -o ./apis
225225

226226
| props | required | type | default | remark |
227227
| --- | --- | --- | --- | --- |
228-
| schemaPath | yes | string | - | Swagger2/OpenAPI3 URL |
228+
| schemaPath | no\* | string | - | Swagger2/OpenAPI3 URL (mutually exclusive with apifoxConfig, one of them is required) |
229+
| apifoxConfig | no\* | [Apifox Config](#Apifox-Config) | - | apifox configs (mutually exclusive with schemaPath, one of them is required) |
229230
| serversPath | no | string | './src/apis' | the folder path for the run results |
230231
| requestLibPath | no | string | 'axios' | custom request lib path, for example: '@/request', 'node-fetch' |
231232
| isSplitTypesByModule | no | boolean | false | split types by module, generates {module}.type.ts (module types), common.type.ts (common types), enum.ts (enum types), types.ts (unified export) |
@@ -248,7 +249,6 @@ openapi -i ./spec.json -o ./apis
248249
| isGenJsonSchemas | no | boolean | false | generate JSON Schemas |
249250
| mockFolder | no | string | - | mock file path, for example: './mocks' |
250251
| authorization | no | string | - | docs authorization |
251-
| apifoxConfig | no | [Apifox Config](#Apifox-Config) | - | apifox configs |
252252
| nullable | no | boolean | false | null instead of optional |
253253
| isTranslateToEnglishTag | no | boolean | false | translate chinese tag name to english tag name |
254254
| isOnlyGenTypeScriptType | no | boolean | false | only generate typescript type |

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,8 @@ openapi --i ./spec.json --o ./apis
225225

226226
| 属性 | 必填 | 类型 | 默认值 | 说明 |
227227
| --- | --- | --- | --- | --- |
228-
| schemaPath || string | - | Swagger2/OpenAPI3 地址 |
228+
| schemaPath |\* | string | - | Swagger2/OpenAPI3 地址(与 apifoxConfig 互斥,两者必填其一) |
229+
| apifoxConfig |\* | [Apifox Config](#Apifox-Config) | - | apifox 配置(与 schemaPath 互斥,两者必填其一) |
229230
| serversPath || string | './src/apis' | 运行结果文件夹路径 |
230231
| requestLibPath || string | 'axios' | 自定义请求方法路径,例如:'@/request'、'node-fetch' |
231232
| isSplitTypesByModule || boolean | false | 按模块拆分类型文件,开启后会生成:{module}.type.ts(各模块类型)、common.type.ts(公共类型)、enum.ts(枚举类型)、types.ts(统一导出) |
@@ -248,7 +249,6 @@ openapi --i ./spec.json --o ./apis
248249
| isGenJsonSchemas || boolean | false | 是否生成 JSON Schemas |
249250
| mockFolder || string | - | mock文件路径,例如:'./mocks' |
250251
| authorization || string | - | 文档权限凭证 |
251-
| apifoxConfig || [Apifox Config](#Apifox-Config) | - | apifox 配置 |
252252
| nullable || boolean | false | 使用 null 代替可选 |
253253
| isTranslateToEnglishTag || boolean | false | 将中文 tag 名称翻译成英文 tag 名称 |
254254
| isOnlyGenTypeScriptType || boolean | false | 仅生成 typescript 类型 |

agents.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ else if (isNodeProject) {
4040

4141
| Configuration | Type | Default | Description | When to Use |
4242
| --- | --- | --- | --- | --- |
43-
| `schemaPath` | string | **required** | OpenAPI/Swagger spec URL or file path | Always required |
43+
| `schemaPath` | string | - | OpenAPI/Swagger spec URL or file path | Use when providing OpenAPI spec URL/file path (mutually exclusive with apifoxConfig) |
44+
| `apifoxConfig` | object | - | Apifox configuration | Use when fetching spec from Apifox (mutually exclusive with schemaPath) |
4445
| `serversPath` | string | `"./src/apis"` | Output directory for generated files | Custom output location |
4546
| `requestLibPath` | string | `"axios"` | HTTP client library path | Custom request client |
4647
| `full` | boolean | `true` | Full replacement vs incremental | Incremental updates |

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
"lint:fix": "eslint ./src --report-unused-disable-directives --max-warnings=0 --fix",
3333
"test:unit": "vitest",
3434
"prepare": "husky",
35-
"openapi-ts-request": "openapi-ts"
35+
"openapi-ts-request": "openapi"
3636
},
3737
"dependencies": {
3838
"@clack/prompts": "^0.11.0",

src/bin/cli.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { GenerateServiceProps } from '../index';
66
import { generateService } from '../index';
77
import { logError } from '../log';
88
import { readConfig } from '../readConfig';
9+
import { createMultiselectOptions } from './utils';
910

1011
program
1112
.option('-cfn, --configFileName <string>', 'config file name')
@@ -44,18 +45,17 @@ async function run() {
4445
intro('🎉 欢迎使用 openapi-ts-request 生成器');
4546
const selected = await multiselect({
4647
message: '请选择要生成的 service',
47-
options: configs.map((config) => ({
48-
value: config,
49-
label: config.describe || config.schemaPath,
50-
})),
48+
options: createMultiselectOptions(configs) as Parameters<
49+
typeof multiselect
50+
>[0]['options'],
5151
});
5252

5353
if (isCancel(selected)) {
5454
cancel('👋 Has cancelled');
5555
process.exit(0);
5656
}
5757

58-
configs = selected;
58+
configs = selected as GenerateServiceProps[];
5959
}
6060

6161
for (const config of configs) {
@@ -70,7 +70,9 @@ async function run() {
7070

7171
if (result.status === 'rejected') {
7272
const cnf = configs[i];
73-
const label = cnf.describe || cnf.schemaPath;
73+
const label =
74+
cnf.describe ||
75+
('schemaPath' in cnf ? cnf.schemaPath : 'Apifox Config');
7476
errorMsg += `${label}${label && ':'}${result.reason}\n`;
7577
}
7678
}

src/bin/openapi.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { generateService } from '../index';
1010
import { logError } from '../log';
1111
import { readConfig } from '../readConfig';
1212
import type { IPriorityRule, IReactQueryMode } from '../type';
13+
import { createMultiselectOptions } from './utils';
1314

1415
const params = program
1516
.name('openapi')
@@ -194,20 +195,20 @@ async function run() {
194195

195196
console.log(''); // 添加一个空行
196197
intro('🎉 欢迎使用 openapi-ts-request 生成器');
198+
197199
const selected = await multiselect({
198200
message: '请选择要生成的 service',
199-
options: configs.map((config) => ({
200-
value: config,
201-
label: config.describe || config.schemaPath,
202-
})),
201+
options: createMultiselectOptions(configs) as Parameters<
202+
typeof multiselect
203+
>[0]['options'],
203204
});
204205

205206
if (isCancel(selected)) {
206207
cancel('👋 Has cancelled');
207208
process.exit(0);
208209
}
209210

210-
configs = selected;
211+
configs = selected as GenerateServiceProps[];
211212
}
212213

213214
for (const config of configs) {
@@ -222,7 +223,9 @@ async function run() {
222223

223224
if (result.status === 'rejected') {
224225
const cnf = configs[i];
225-
const label = cnf.describe || cnf.schemaPath;
226+
const label =
227+
cnf.describe ||
228+
('schemaPath' in cnf ? cnf.schemaPath : 'Apifox Config');
226229
errorMsg += `${label}${label && ':'}${result.reason}\n`;
227230
}
228231
}

src/bin/utils.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { GenerateServiceProps } from '../index';
2+
3+
/**
4+
* Helper function to create multiselect options with proper typing
5+
*/
6+
export function createMultiselectOptions(
7+
configs: GenerateServiceProps[]
8+
): Array<{ value: GenerateServiceProps; label: string }> {
9+
return configs.map((config) => ({
10+
value: config,
11+
label:
12+
config.describe ||
13+
('schemaPath' in config ? config.schemaPath : 'Apifox Config'),
14+
}));
15+
}

src/index.ts

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {
1414
ComponentsObject,
1515
IPriorityRule,
1616
IReactQueryMode,
17+
MutuallyExclusive,
1718
OpenAPIObject,
1819
OperationObject,
1920
ReferenceObject,
@@ -29,11 +30,7 @@ import {
2930

3031
export * from './generator/patchSchema';
3132

32-
export type GenerateServiceProps = {
33-
/**
34-
* Swagger2/OpenAPI3 地址
35-
*/
36-
schemaPath: string;
33+
export type GenerateServicePropsBase = {
3734
/**
3835
* 生成的文件夹的路径
3936
*/
@@ -141,10 +138,6 @@ export type GenerateServiceProps = {
141138
* 文档权限凭证
142139
*/
143140
authorization?: string;
144-
/**
145-
* apifox 配置
146-
*/
147-
apifoxConfig?: GetSchemaByApifoxProps;
148141
/**
149142
* 默认为false,true时使用null代替可选值
150143
*/
@@ -365,6 +358,21 @@ export type GenerateServiceProps = {
365358
};
366359
};
367360

361+
/**
362+
* Swagger2/OpenAPI3 地址或 Apifox 配置,两者必须填写一个
363+
*/
364+
export type GenerateServiceProps = GenerateServicePropsBase &
365+
MutuallyExclusive<{
366+
/**
367+
* Swagger2/OpenAPI3 地址
368+
*/
369+
schemaPath: string;
370+
/**
371+
* apifox 配置
372+
*/
373+
apifoxConfig: GetSchemaByApifoxProps;
374+
}>;
375+
368376
export async function generateService({
369377
requestLibPath,
370378
schemaPath,
@@ -382,7 +390,15 @@ export async function generateService({
382390
...rest
383391
}: GenerateServiceProps) {
384392
if (!schemaPath && !apifoxConfig) {
385-
return;
393+
throw new Error(
394+
'Either schemaPath or apifoxConfig must be provided. Please provide at least one configuration option.'
395+
);
396+
}
397+
398+
if (schemaPath && apifoxConfig) {
399+
throw new Error(
400+
'schemaPath and apifoxConfig cannot be provided at the same time. Please provide only one configuration option.'
401+
);
386402
}
387403

388404
let openAPI: OpenAPIObject | null = null;
@@ -415,7 +431,7 @@ export async function generateService({
415431
const requestImportStatement = getImportStatement(requestLibPath);
416432
const serviceGenerator = new ServiceGenerator(
417433
{
418-
schemaPath,
434+
...(schemaPath ? { schemaPath } : { apifoxConfig }),
419435
serversPath: './src/apis',
420436
requestImportStatement,
421437
enableLogging: false,
@@ -447,7 +463,7 @@ export async function generateService({
447463
isSupportParseEnumDesc: false,
448464
full: true,
449465
...rest,
450-
},
466+
} as GenerateServiceProps,
451467
openAPI
452468
);
453469
serviceGenerator.genFile();

0 commit comments

Comments
 (0)