openapi-ts-request 1.12.1 → 1.12.3
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 +2 -2
- package/dist/bin/cli.js +4 -5
- package/dist/bin/openapi.js +4 -5
- package/dist/bin/utils.d.ts +8 -0
- package/dist/bin/utils.js +13 -0
- package/dist/generator/serviceGeneratorHelper.js +19 -3
- package/dist/generator/util.js +10 -0
- package/dist/index.d.ts +15 -10
- package/dist/index.js +6 -3
- package/dist/parser-mock/index.js +7 -3
- package/dist/parser-mock/util.d.ts +1 -1
- package/dist/type.d.ts +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -225,7 +225,8 @@ openapi --i ./spec.json --o ./apis
|
|
|
225
225
|
|
|
226
226
|
| 属性 | 必填 | 类型 | 默认值 | 说明 |
|
|
227
227
|
| --- | --- | --- | --- | --- |
|
|
228
|
-
| schemaPath |
|
|
228
|
+
| schemaPath | 否\* | string | - | Swagger2/OpenAPI3 地址(与 apifoxConfig 互斥,两者必填其一) |
|
|
229
|
+
| apifoxConfig | 否\* | [Apifox Config](#Apifox-Config) | - | apifox 配置(与 schemaPath 互斥,两者必填其一) |
|
|
229
230
|
| serversPath | 否 | string | './src/apis' | 运行结果文件夹路径 |
|
|
230
231
|
| requestLibPath | 否 | string | 'axios' | 自定义请求方法路径,例如:'@/request'、'node-fetch' |
|
|
231
232
|
| isSplitTypesByModule | 否 | boolean | false | 按模块拆分类型文件,开启后会生成:{module}.type.ts(各模块类型)、common.type.ts(公共类型)、enum.ts(枚举类型)、types.ts(统一导出) |
|
|
@@ -248,7 +249,6 @@ openapi --i ./spec.json --o ./apis
|
|
|
248
249
|
| isGenJsonSchemas | 否 | boolean | false | 是否生成 JSON Schemas |
|
|
249
250
|
| mockFolder | 否 | string | - | mock文件路径,例如:'./mocks' |
|
|
250
251
|
| authorization | 否 | string | - | 文档权限凭证 |
|
|
251
|
-
| apifoxConfig | 否 | [Apifox Config](#Apifox-Config) | - | apifox 配置 |
|
|
252
252
|
| nullable | 否 | boolean | false | 使用 null 代替可选 |
|
|
253
253
|
| isTranslateToEnglishTag | 否 | boolean | false | 将中文 tag 名称翻译成英文 tag 名称 |
|
|
254
254
|
| isOnlyGenTypeScriptType | 否 | boolean | false | 仅生成 typescript 类型 |
|
package/dist/bin/cli.js
CHANGED
|
@@ -7,6 +7,7 @@ const commander_1 = require("commander");
|
|
|
7
7
|
const index_1 = require("../index");
|
|
8
8
|
const log_1 = require("../log");
|
|
9
9
|
const readConfig_1 = require("../readConfig");
|
|
10
|
+
const utils_1 = require("./utils");
|
|
10
11
|
commander_1.program
|
|
11
12
|
.option('-cfn, --configFileName <string>', 'config file name')
|
|
12
13
|
.option('-cfp, --configFilePath <string>', 'config file path');
|
|
@@ -38,10 +39,7 @@ function run() {
|
|
|
38
39
|
(0, prompts_1.intro)('🎉 欢迎使用 openapi-ts-request 生成器');
|
|
39
40
|
const selected = yield (0, prompts_1.multiselect)({
|
|
40
41
|
message: '请选择要生成的 service',
|
|
41
|
-
options:
|
|
42
|
-
value: config,
|
|
43
|
-
label: config.describe || config.schemaPath,
|
|
44
|
-
})),
|
|
42
|
+
options: (0, utils_1.createMultiselectOptions)(configs),
|
|
45
43
|
});
|
|
46
44
|
if ((0, prompts_1.isCancel)(selected)) {
|
|
47
45
|
(0, prompts_1.cancel)('👋 Has cancelled');
|
|
@@ -58,7 +56,8 @@ function run() {
|
|
|
58
56
|
const result = results[i];
|
|
59
57
|
if (result.status === 'rejected') {
|
|
60
58
|
const cnf = configs[i];
|
|
61
|
-
const label = cnf.describe ||
|
|
59
|
+
const label = cnf.describe ||
|
|
60
|
+
('schemaPath' in cnf ? cnf.schemaPath : 'Apifox Config');
|
|
62
61
|
errorMsg += `${label}${label && ':'}${result.reason}\n`;
|
|
63
62
|
}
|
|
64
63
|
}
|
package/dist/bin/openapi.js
CHANGED
|
@@ -10,6 +10,7 @@ const pkg = tslib_1.__importStar(require("../../package.json"));
|
|
|
10
10
|
const index_1 = require("../index");
|
|
11
11
|
const log_1 = require("../log");
|
|
12
12
|
const readConfig_1 = require("../readConfig");
|
|
13
|
+
const utils_1 = require("./utils");
|
|
13
14
|
const params = commander_1.program
|
|
14
15
|
.name('openapi')
|
|
15
16
|
.usage('[options]')
|
|
@@ -112,10 +113,7 @@ function run() {
|
|
|
112
113
|
(0, prompts_1.intro)('🎉 欢迎使用 openapi-ts-request 生成器');
|
|
113
114
|
const selected = yield (0, prompts_1.multiselect)({
|
|
114
115
|
message: '请选择要生成的 service',
|
|
115
|
-
options:
|
|
116
|
-
value: config,
|
|
117
|
-
label: config.describe || config.schemaPath,
|
|
118
|
-
})),
|
|
116
|
+
options: (0, utils_1.createMultiselectOptions)(configs),
|
|
119
117
|
});
|
|
120
118
|
if ((0, prompts_1.isCancel)(selected)) {
|
|
121
119
|
(0, prompts_1.cancel)('👋 Has cancelled');
|
|
@@ -132,7 +130,8 @@ function run() {
|
|
|
132
130
|
const result = results[i];
|
|
133
131
|
if (result.status === 'rejected') {
|
|
134
132
|
const cnf = configs[i];
|
|
135
|
-
const label = cnf.describe ||
|
|
133
|
+
const label = cnf.describe ||
|
|
134
|
+
('schemaPath' in cnf ? cnf.schemaPath : 'Apifox Config');
|
|
136
135
|
errorMsg += `${label}${label && ':'}${result.reason}\n`;
|
|
137
136
|
}
|
|
138
137
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { GenerateServiceProps } from '../index';
|
|
2
|
+
/**
|
|
3
|
+
* Helper function to create multiselect options with proper typing
|
|
4
|
+
*/
|
|
5
|
+
export declare function createMultiselectOptions(configs: GenerateServiceProps[]): Array<{
|
|
6
|
+
value: GenerateServiceProps;
|
|
7
|
+
label: string;
|
|
8
|
+
}>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createMultiselectOptions = createMultiselectOptions;
|
|
4
|
+
/**
|
|
5
|
+
* Helper function to create multiselect options with proper typing
|
|
6
|
+
*/
|
|
7
|
+
function createMultiselectOptions(configs) {
|
|
8
|
+
return configs.map((config) => ({
|
|
9
|
+
value: config,
|
|
10
|
+
label: config.describe ||
|
|
11
|
+
('schemaPath' in config ? config.schemaPath : 'Apifox Config'),
|
|
12
|
+
}));
|
|
13
|
+
}
|
|
@@ -56,7 +56,16 @@ function resolveEnumObject(params) {
|
|
|
56
56
|
const enumArray = schemaObject.enum;
|
|
57
57
|
let enumStr = '';
|
|
58
58
|
let enumLabelTypeStr = '';
|
|
59
|
-
|
|
59
|
+
// 获取实际的类型(处理 OpenAPI 3.1 的 type 数组情况)
|
|
60
|
+
const getActualType = (type) => {
|
|
61
|
+
if (Array.isArray(type)) {
|
|
62
|
+
// 如果是数组,返回第一个非 null 类型
|
|
63
|
+
return type.find((t) => t !== 'null') || 'string';
|
|
64
|
+
}
|
|
65
|
+
return type;
|
|
66
|
+
};
|
|
67
|
+
const actualType = getActualType(schemaObject.type);
|
|
68
|
+
if (config_2.numberEnum.includes(actualType) || (0, util_1.isAllNumber)(enumArray)) {
|
|
60
69
|
if (config.isSupportParseEnumDesc && schemaObject.description) {
|
|
61
70
|
const enumMap = (0, util_1.parseDescriptionEnum)(schemaObject.description);
|
|
62
71
|
enumStr = `{${(0, lodash_1.map)(enumArray, (value) => {
|
|
@@ -95,7 +104,7 @@ function resolveEnumObject(params) {
|
|
|
95
104
|
}).join(',')}}`;
|
|
96
105
|
}
|
|
97
106
|
else {
|
|
98
|
-
if (config_2.numberEnum.includes(
|
|
107
|
+
if (config_2.numberEnum.includes(actualType) || (0, util_1.isAllNumber)(enumArray)) {
|
|
99
108
|
if ((config.isSupportParseEnumDesc || config.supportParseEnumDescByReg) &&
|
|
100
109
|
schemaObject.description) {
|
|
101
110
|
const enumMap = config.isSupportParseEnumDesc
|
|
@@ -225,7 +234,14 @@ function resolveRefObject(params) {
|
|
|
225
234
|
}
|
|
226
235
|
else {
|
|
227
236
|
const schemaObj = schema;
|
|
228
|
-
|
|
237
|
+
// 处理 OpenAPI 3.1 的 type 数组情况
|
|
238
|
+
if (Array.isArray(schemaObj.type)) {
|
|
239
|
+
// 如果是数组,使用第一个非 null 类型
|
|
240
|
+
resolvedType = schemaObj.type.find((t) => t !== 'null') || 'string';
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
resolvedType = schemaObj.type;
|
|
244
|
+
}
|
|
229
245
|
}
|
|
230
246
|
const finalSchema = schema;
|
|
231
247
|
return Object.assign(Object.assign({}, (resolvedSchema || {})), { type: resolvedType || finalSchema.type });
|
package/dist/generator/util.js
CHANGED
|
@@ -104,6 +104,16 @@ function getDefaultType(schemaObject, namespace = '', schemas) {
|
|
|
104
104
|
let type = schemaObject === null || schemaObject === void 0 ? void 0 : schemaObject.type;
|
|
105
105
|
const dateEnum = ['Date', 'date', 'dateTime', 'date-time', 'datetime'];
|
|
106
106
|
const stringEnum = ['string', 'email', 'password', 'url', 'byte', 'binary'];
|
|
107
|
+
// OpenAPI 3.1 支持 type 为数组,例如 ["string", "null"]
|
|
108
|
+
if (Array.isArray(type)) {
|
|
109
|
+
return type
|
|
110
|
+
.map((t) => {
|
|
111
|
+
// 为数组中的每个类型创建一个临时的 schemaObject
|
|
112
|
+
const tempSchema = Object.assign(Object.assign({}, schemaObject), { type: t });
|
|
113
|
+
return getDefaultType(tempSchema, namespace, schemas);
|
|
114
|
+
})
|
|
115
|
+
.join(' | ');
|
|
116
|
+
}
|
|
107
117
|
if (type === 'null') {
|
|
108
118
|
return 'null';
|
|
109
119
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import type { TypescriptFileType } from './generator/config';
|
|
2
2
|
import type { APIDataType, ControllerType, ISchemaItem, ITypeItem } from './generator/type';
|
|
3
|
-
import type { ComponentsObject, IPriorityRule, IReactQueryMode, OpenAPIObject, OperationObject, ReferenceObject, SchemaObject } from './type';
|
|
3
|
+
import type { ComponentsObject, IPriorityRule, IReactQueryMode, MutuallyExclusive, OpenAPIObject, OperationObject, ReferenceObject, SchemaObject } from './type';
|
|
4
4
|
import { type GetSchemaByApifoxProps } from './type';
|
|
5
5
|
export * from './generator/patchSchema';
|
|
6
|
-
export type
|
|
7
|
-
/**
|
|
8
|
-
* Swagger2/OpenAPI3 地址
|
|
9
|
-
*/
|
|
10
|
-
schemaPath: string;
|
|
6
|
+
export type GenerateServicePropsBase = {
|
|
11
7
|
/**
|
|
12
8
|
* 生成的文件夹的路径
|
|
13
9
|
*/
|
|
@@ -113,10 +109,6 @@ export type GenerateServiceProps = {
|
|
|
113
109
|
* 文档权限凭证
|
|
114
110
|
*/
|
|
115
111
|
authorization?: string;
|
|
116
|
-
/**
|
|
117
|
-
* apifox 配置
|
|
118
|
-
*/
|
|
119
|
-
apifoxConfig?: GetSchemaByApifoxProps;
|
|
120
112
|
/**
|
|
121
113
|
* 默认为false,true时使用null代替可选值
|
|
122
114
|
*/
|
|
@@ -291,6 +283,19 @@ export type GenerateServiceProps = {
|
|
|
291
283
|
};
|
|
292
284
|
};
|
|
293
285
|
};
|
|
286
|
+
/**
|
|
287
|
+
* Swagger2/OpenAPI3 地址或 Apifox 配置,两者必须填写一个
|
|
288
|
+
*/
|
|
289
|
+
export type GenerateServiceProps = GenerateServicePropsBase & MutuallyExclusive<{
|
|
290
|
+
/**
|
|
291
|
+
* Swagger2/OpenAPI3 地址
|
|
292
|
+
*/
|
|
293
|
+
schemaPath: string;
|
|
294
|
+
/**
|
|
295
|
+
* apifox 配置
|
|
296
|
+
*/
|
|
297
|
+
apifoxConfig: GetSchemaByApifoxProps;
|
|
298
|
+
}>;
|
|
294
299
|
export declare function generateService({ requestLibPath, schemaPath, mockFolder, includeTags, excludeTags, includePaths, excludePaths, authorization, isTranslateToEnglishTag, priorityRule, timeout, reactQueryMode, apifoxConfig, ...rest }: GenerateServiceProps): Promise<void>;
|
|
295
300
|
/**
|
|
296
301
|
* Defines the configuration for openapi-ts-request.
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,10 @@ function generateService(_a) {
|
|
|
13
13
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
14
14
|
var { requestLibPath, schemaPath, mockFolder, includeTags, excludeTags, includePaths, excludePaths, authorization, isTranslateToEnglishTag, priorityRule = config_1.PriorityRule.include, timeout = 60000, reactQueryMode = config_1.ReactQueryMode.react, apifoxConfig } = _a, rest = tslib_1.__rest(_a, ["requestLibPath", "schemaPath", "mockFolder", "includeTags", "excludeTags", "includePaths", "excludePaths", "authorization", "isTranslateToEnglishTag", "priorityRule", "timeout", "reactQueryMode", "apifoxConfig"]);
|
|
15
15
|
if (!schemaPath && !apifoxConfig) {
|
|
16
|
-
|
|
16
|
+
throw new Error('Either schemaPath or apifoxConfig must be provided. Please provide at least one configuration option.');
|
|
17
|
+
}
|
|
18
|
+
if (schemaPath && apifoxConfig) {
|
|
19
|
+
throw new Error('schemaPath and apifoxConfig cannot be provided at the same time. Please provide only one configuration option.');
|
|
17
20
|
}
|
|
18
21
|
let openAPI = null;
|
|
19
22
|
if (apifoxConfig) {
|
|
@@ -34,7 +37,7 @@ function generateService(_a) {
|
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
const requestImportStatement = (0, util_1.getImportStatement)(requestLibPath);
|
|
37
|
-
const serviceGenerator = new serviceGenarator_1.default(Object.assign({ schemaPath, serversPath: './src/apis', requestImportStatement, enableLogging: false, priorityRule, includeTags: includeTags
|
|
40
|
+
const serviceGenerator = new serviceGenarator_1.default(Object.assign(Object.assign(Object.assign({}, (schemaPath ? { schemaPath } : { apifoxConfig })), { serversPath: './src/apis', requestImportStatement, enableLogging: false, priorityRule, includeTags: includeTags
|
|
38
41
|
? includeTags
|
|
39
42
|
: priorityRule === config_1.PriorityRule.include ||
|
|
40
43
|
priorityRule === config_1.PriorityRule.both
|
|
@@ -44,7 +47,7 @@ function generateService(_a) {
|
|
|
44
47
|
: priorityRule === config_1.PriorityRule.include ||
|
|
45
48
|
priorityRule === config_1.PriorityRule.both
|
|
46
49
|
? [/.*/g]
|
|
47
|
-
: null, excludeTags: excludeTags ? excludeTags : null, excludePaths: excludePaths ? excludePaths : null, requestOptionsType: '{[key: string]: unknown}', namespace: 'API', isGenReactQuery: false, reactQueryMode, isGenJavaScript: false, isDisplayTypeLabel: false, isGenJsonSchemas: false, nullable: false, isOnlyGenTypeScriptType: false, isCamelCase: true, isSupportParseEnumDesc: false, full: true }, rest), openAPI);
|
|
50
|
+
: null, excludeTags: excludeTags ? excludeTags : null, excludePaths: excludePaths ? excludePaths : null, requestOptionsType: '{[key: string]: unknown}', namespace: 'API', isGenReactQuery: false, reactQueryMode, isGenJavaScript: false, isDisplayTypeLabel: false, isGenJsonSchemas: false, nullable: false, isOnlyGenTypeScriptType: false, isCamelCase: true, isSupportParseEnumDesc: false, full: true }), rest), openAPI);
|
|
48
51
|
serviceGenerator.genFile();
|
|
49
52
|
if (mockFolder) {
|
|
50
53
|
(0, mockGenarator_1.mockGenerator)({
|
|
@@ -86,10 +86,14 @@ function getDateByName(name, parentsKey) {
|
|
|
86
86
|
function primitive(schemaParams, propsName) {
|
|
87
87
|
const schema = (0, util_2.objectify)(schemaParams);
|
|
88
88
|
const { type, format } = schema;
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
// 处理 OpenAPI 3.1 的 type 数组情况
|
|
90
|
+
const actualType = Array.isArray(type)
|
|
91
|
+
? type.find((t) => t !== 'null') || 'string'
|
|
92
|
+
: type;
|
|
93
|
+
const value = primitives_1.primitives[`${actualType}_${format || getDateByName(propsName)}`] ||
|
|
94
|
+
primitives_1.primitives[actualType];
|
|
91
95
|
if ((0, lodash_1.isUndefined)(schema.example)) {
|
|
92
|
-
return value || `Unknown Type: ${
|
|
96
|
+
return value || `Unknown Type: ${actualType}`;
|
|
93
97
|
}
|
|
94
98
|
return schema.example;
|
|
95
99
|
}
|
|
@@ -3,7 +3,7 @@ import type { OpenAPIObject, ParameterObject, ReferenceObject, SchemaObject } fr
|
|
|
3
3
|
export declare function objectify<T>(thing: T): T;
|
|
4
4
|
export declare function get(openAPI: OpenAPIObject, path: string): OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject;
|
|
5
5
|
export declare function normalizeArray(arr: string[] | string): string[];
|
|
6
|
-
export declare function inferSchema(thing: ParameterObject | SchemaObject | ReferenceObject | OpenAPIV3.MediaTypeObject): OpenAPIV3.ReferenceObject | OpenAPIV3.MediaTypeObject | {
|
|
6
|
+
export declare function inferSchema(thing: ParameterObject | SchemaObject | ReferenceObject | OpenAPIV3.MediaTypeObject): import("../type").NonArraySchemaObject | OpenAPIV3.ReferenceObject | OpenAPIV3.MediaTypeObject | {
|
|
7
7
|
type: string;
|
|
8
8
|
enum?: any[];
|
|
9
9
|
title?: string;
|
package/dist/type.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export type MutuallyExclusiveWithFallback<T, N> = {
|
|
|
16
16
|
}[keyof T];
|
|
17
17
|
type Modify<T, R> = Omit<T, keyof R> & R;
|
|
18
18
|
type ICustomBaseSchemaObject = {
|
|
19
|
-
type: ISchemaObjectType;
|
|
19
|
+
type: ISchemaObjectType | ISchemaObjectType[];
|
|
20
20
|
format?: ISchemaObjectFormat;
|
|
21
21
|
additionalProperties?: boolean | ISchemaObject;
|
|
22
22
|
properties?: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openapi-ts-request",
|
|
3
|
-
"version": "1.12.
|
|
3
|
+
"version": "1.12.3",
|
|
4
4
|
"description": "Swagger2/OpenAPI3/Apifox to TypeScript/JavaScript, request client(support any client), request mock service, enum and enum translation, react-query/vue-query, type field label, JSON Schemas",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18.0.0",
|
|
@@ -96,6 +96,6 @@
|
|
|
96
96
|
"lint": "eslint ./src --report-unused-disable-directives --max-warnings=0",
|
|
97
97
|
"lint:fix": "eslint ./src --report-unused-disable-directives --max-warnings=0 --fix",
|
|
98
98
|
"test:unit": "vitest",
|
|
99
|
-
"openapi-ts-request": "openapi
|
|
99
|
+
"openapi-ts-request": "openapi"
|
|
100
100
|
}
|
|
101
101
|
}
|