openapi-ts-request 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -2
- package/dist/bin/cli.js +30 -11
- package/dist/bin/openapi.js +80 -31
- package/dist/generator/merge.d.ts +6 -0
- package/dist/generator/merge.js +267 -0
- package/dist/generator/mockGenarator.js +1 -1
- package/dist/generator/serviceGenarator.js +86 -59
- package/dist/generator/type.d.ts +16 -1
- package/dist/generator/type.js +6 -0
- package/dist/index.d.ts +19 -3
- package/dist/index.js +11 -5
- package/dist/log.d.ts +1 -0
- package/dist/log.js +3 -0
- package/dist/readConfig.d.ts +2 -0
- package/dist/readConfig.js +31 -0
- package/dist/type.d.ts +42 -0
- package/dist/util.d.ts +17 -2
- package/dist/util.js +104 -7
- package/package.json +4 -2
|
@@ -10,10 +10,12 @@ const path_1 = require("path");
|
|
|
10
10
|
const rimraf_1 = require("rimraf");
|
|
11
11
|
const config_1 = require("../config");
|
|
12
12
|
const log_1 = tslib_1.__importDefault(require("../log"));
|
|
13
|
+
const util_1 = require("../util");
|
|
13
14
|
const config_2 = require("./config");
|
|
14
15
|
const file_1 = require("./file");
|
|
16
|
+
const merge_1 = require("./merge");
|
|
15
17
|
const patchSchema_1 = require("./patchSchema");
|
|
16
|
-
const
|
|
18
|
+
const util_2 = require("./util");
|
|
17
19
|
class ServiceGenerator {
|
|
18
20
|
constructor(config, openAPIData) {
|
|
19
21
|
var _a, _b, _c, _d, _e;
|
|
@@ -81,7 +83,7 @@ class ServiceGenerator {
|
|
|
81
83
|
if (!operationObject) {
|
|
82
84
|
return;
|
|
83
85
|
}
|
|
84
|
-
const hookCustomFileNames = ((_a = this.config.hook) === null || _a === void 0 ? void 0 : _a.customFileNames) ||
|
|
86
|
+
const hookCustomFileNames = ((_a = this.config.hook) === null || _a === void 0 ? void 0 : _a.customFileNames) || util_2.getDefaultFileTag;
|
|
85
87
|
const tags = hookCustomFileNames(operationObject, pathKey, method);
|
|
86
88
|
// 这里判断tags
|
|
87
89
|
tags.forEach((tag) => {
|
|
@@ -119,8 +121,8 @@ class ServiceGenerator {
|
|
|
119
121
|
}
|
|
120
122
|
}
|
|
121
123
|
const tagKey = this.config.isCamelCase
|
|
122
|
-
? (0,
|
|
123
|
-
: (0,
|
|
124
|
+
? (0, util_1.camelCase)((0, util_2.resolveTypeName)(tag))
|
|
125
|
+
: (0, util_2.resolveTypeName)(tag);
|
|
124
126
|
if (!this.apiData[tagKey]) {
|
|
125
127
|
this.apiData[tagKey] = [];
|
|
126
128
|
}
|
|
@@ -130,15 +132,17 @@ class ServiceGenerator {
|
|
|
130
132
|
}
|
|
131
133
|
}
|
|
132
134
|
genFile() {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
(
|
|
135
|
+
if (this.config.full) {
|
|
136
|
+
try {
|
|
137
|
+
(0, glob_1.globSync)(`${this.config.serversPath}/**/*`)
|
|
138
|
+
.filter((item) => !item.includes('_deperated'))
|
|
139
|
+
.forEach((item) => {
|
|
140
|
+
(0, rimraf_1.rimrafSync)(item);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
(0, log_1.default)(`🚥 api 生成失败: ${error}`);
|
|
145
|
+
}
|
|
142
146
|
}
|
|
143
147
|
const isOnlyGenTypeScriptType = this.config.isOnlyGenTypeScriptType;
|
|
144
148
|
const isGenJavaScript = this.config.isGenJavaScript;
|
|
@@ -146,7 +150,7 @@ class ServiceGenerator {
|
|
|
146
150
|
const reactQueryFileName = (0, config_2.displayReactQueryFileName)(reactQueryMode);
|
|
147
151
|
// 处理重复的 typeName
|
|
148
152
|
const interfaceTPConfigs = this.getInterfaceTPConfigs();
|
|
149
|
-
(0,
|
|
153
|
+
(0, util_2.handleDuplicateTypeNames)(interfaceTPConfigs);
|
|
150
154
|
// 生成 ts 类型声明
|
|
151
155
|
if (!isGenJavaScript) {
|
|
152
156
|
this.genFileFromTemplate(`${config_2.interfaceFileName}.ts`, config_2.TypescriptFileType.interface, {
|
|
@@ -180,13 +184,13 @@ class ServiceGenerator {
|
|
|
180
184
|
// 生成 service controller 文件
|
|
181
185
|
this.getServiceTPConfigs().forEach((tp) => {
|
|
182
186
|
const hasError = this.genFileFromTemplate(isGenJavaScript
|
|
183
|
-
? (0,
|
|
184
|
-
: (0,
|
|
187
|
+
? (0, util_2.getFinalFileName)(`${tp.className}.js`)
|
|
188
|
+
: (0, util_2.getFinalFileName)(`${tp.className}.ts`), config_2.TypescriptFileType.serviceController, Object.assign({ namespace: this.config.namespace, requestOptionsType: this.config.requestOptionsType, requestImportStatement: this.config.requestImportStatement, interfaceFileName: config_2.interfaceFileName }, tp));
|
|
185
189
|
prettierError.push(hasError);
|
|
186
190
|
if (this.config.isGenReactQuery) {
|
|
187
191
|
this.genFileFromTemplate(isGenJavaScript
|
|
188
|
-
? (0,
|
|
189
|
-
: (0,
|
|
192
|
+
? (0, util_2.getFinalFileName)(`${tp.className}.${reactQueryFileName}.js`)
|
|
193
|
+
: (0, util_2.getFinalFileName)(`${tp.className}.${reactQueryFileName}.ts`), config_2.TypescriptFileType.reactQuery, Object.assign({ namespace: this.config.namespace, requestOptionsType: this.config.requestOptionsType, requestImportStatement: this.config.requestImportStatement, interfaceFileName: config_2.interfaceFileName, reactQueryModePackageName: (0, config_1.displayReactQueryMode)(reactQueryMode) }, tp));
|
|
190
194
|
}
|
|
191
195
|
});
|
|
192
196
|
if (prettierError.includes(true)) {
|
|
@@ -197,7 +201,7 @@ class ServiceGenerator {
|
|
|
197
201
|
this.config.isGenJsonSchemas &&
|
|
198
202
|
!(0, lodash_1.isEmpty)(this.schemaList)) {
|
|
199
203
|
// 处理重复的 schemaName
|
|
200
|
-
(0,
|
|
204
|
+
(0, util_2.handleDuplicateTypeNames)(this.schemaList);
|
|
201
205
|
// 生成 schema 文件
|
|
202
206
|
this.genFileFromTemplate(isGenJavaScript ? `${config_2.schemaFileName}.js` : `${config_2.schemaFileName}.ts`, config_2.TypescriptFileType.schema, {
|
|
203
207
|
list: this.schemaList,
|
|
@@ -225,7 +229,7 @@ class ServiceGenerator {
|
|
|
225
229
|
displayTypeLabelFileName: config_2.displayTypeLabelFileName,
|
|
226
230
|
});
|
|
227
231
|
// 打印日志
|
|
228
|
-
(0, log_1.default)('✅ 成功生成 api
|
|
232
|
+
(0, log_1.default)('✅ 成功生成 api 文件目录-> ', this.config.serversPath);
|
|
229
233
|
}
|
|
230
234
|
getInterfaceTPConfigs() {
|
|
231
235
|
var _a, _b;
|
|
@@ -238,7 +242,7 @@ class ServiceGenerator {
|
|
|
238
242
|
(0, lodash_1.forEach)(config_2.methods, (method) => {
|
|
239
243
|
var _a, _b, _c, _d;
|
|
240
244
|
const operationObject = pathItem[method];
|
|
241
|
-
const hookCustomFileNames = ((_a = this.config.hook) === null || _a === void 0 ? void 0 : _a.customFileNames) ||
|
|
245
|
+
const hookCustomFileNames = ((_a = this.config.hook) === null || _a === void 0 ? void 0 : _a.customFileNames) || util_2.getDefaultFileTag;
|
|
242
246
|
if (!operationObject) {
|
|
243
247
|
return;
|
|
244
248
|
}
|
|
@@ -251,7 +255,7 @@ class ServiceGenerator {
|
|
|
251
255
|
return;
|
|
252
256
|
}
|
|
253
257
|
// 筛选出 pathItem 包含的 $ref 对应的schema
|
|
254
|
-
(0,
|
|
258
|
+
(0, util_2.markAllowedSchema)(JSON.stringify(pathItem), this.openAPIData);
|
|
255
259
|
operationObject.parameters = (_b = operationObject.parameters) === null || _b === void 0 ? void 0 : _b.filter((item) => (item === null || item === void 0 ? void 0 : item.in) !== `${config_2.parametersInsEnum.header}`);
|
|
256
260
|
const props = [];
|
|
257
261
|
(_c = operationObject.parameters) === null || _c === void 0 ? void 0 : _c.forEach((parameter) => {
|
|
@@ -312,14 +316,14 @@ class ServiceGenerator {
|
|
|
312
316
|
type: enumObj.type,
|
|
313
317
|
props: [],
|
|
314
318
|
isEnum: enumObj.isEnum,
|
|
315
|
-
displayLabelFuncName: (0,
|
|
319
|
+
displayLabelFuncName: (0, util_1.camelCase)(`display-${item.name}-Enum`),
|
|
316
320
|
enumLabelType: enumObj.enumLabelType,
|
|
317
321
|
});
|
|
318
322
|
}
|
|
319
323
|
});
|
|
320
324
|
}
|
|
321
325
|
const isEnum = result.isEnum;
|
|
322
|
-
const typeName = (0,
|
|
326
|
+
const typeName = (0, util_2.resolveTypeName)(schemaKey);
|
|
323
327
|
if (typeName) {
|
|
324
328
|
lastTypes.push({
|
|
325
329
|
typeName,
|
|
@@ -327,14 +331,14 @@ class ServiceGenerator {
|
|
|
327
331
|
props: (result.props || []),
|
|
328
332
|
isEnum,
|
|
329
333
|
displayLabelFuncName: isEnum
|
|
330
|
-
? (0,
|
|
334
|
+
? (0, util_1.camelCase)(`display-${typeName}-Enum`)
|
|
331
335
|
: '',
|
|
332
336
|
enumLabelType: isEnum ? result.enumLabelType : '',
|
|
333
337
|
});
|
|
334
338
|
}
|
|
335
339
|
if (this.config.isGenJsonSchemas) {
|
|
336
340
|
this.schemaList.push({
|
|
337
|
-
typeName: `$${(0,
|
|
341
|
+
typeName: `$${(0, util_2.resolveTypeName)(schemaKey)}`,
|
|
338
342
|
type: JSON.stringify((0, patchSchema_1.patchSchema)(schema, (_a = this.openAPIData.components) === null || _a === void 0 ? void 0 : _a.schemas)),
|
|
339
343
|
});
|
|
340
344
|
}
|
|
@@ -416,7 +420,7 @@ class ServiceGenerator {
|
|
|
416
420
|
return `$\{${prefix}}${formattedPath}`;
|
|
417
421
|
};
|
|
418
422
|
return Object.assign(Object.assign({}, newApi), { functionName: this.config.isCamelCase
|
|
419
|
-
? (0,
|
|
423
|
+
? (0, util_1.camelCase)(functionName)
|
|
420
424
|
: functionName, typeName: this.getFunctionParamsTypeName(newApi), path: getPrefixPath(), pathInComment: formattedPath.replace(/\*/g, '*'), apifoxRunLink: newApi === null || newApi === void 0 ? void 0 : newApi['x-run-in-apifox'], hasPathVariables: formattedPath.includes('{'), hasApiPrefix: !!this.config.apiPrefix, method: newApi.method,
|
|
421
425
|
// 如果 functionName 和 summary 相同,则不显示 summary
|
|
422
426
|
desc: functionName === newApi.summary
|
|
@@ -440,7 +444,7 @@ class ServiceGenerator {
|
|
|
440
444
|
})
|
|
441
445
|
// 排序下,防止git乱
|
|
442
446
|
.sort((a, b) => a.path.localeCompare(b.path));
|
|
443
|
-
const fileName = (0,
|
|
447
|
+
const fileName = (0, util_2.replaceDot)(tag) || `api${index}`;
|
|
444
448
|
let className = fileName;
|
|
445
449
|
if ((_a = this.config.hook) === null || _a === void 0 ? void 0 : _a.customClassName) {
|
|
446
450
|
className = this.config.hook.customClassName(tag);
|
|
@@ -467,8 +471,27 @@ class ServiceGenerator {
|
|
|
467
471
|
const env = nunjucks_1.default.configure({
|
|
468
472
|
autoescape: false,
|
|
469
473
|
});
|
|
470
|
-
env.addFilter('capitalizeFirst',
|
|
471
|
-
|
|
474
|
+
env.addFilter('capitalizeFirst', util_2.capitalizeFirstLetter);
|
|
475
|
+
const destPath = (0, path_1.join)(this.config.serversPath, fileName);
|
|
476
|
+
const destCode = nunjucks_1.default.renderString(template, Object.assign({ disableTypeCheck: false }, params));
|
|
477
|
+
let mergerProps = {};
|
|
478
|
+
if ((0, fs_1.existsSync)(destPath)) {
|
|
479
|
+
mergerProps = {
|
|
480
|
+
srcPath: destPath,
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
else {
|
|
484
|
+
mergerProps = {
|
|
485
|
+
source: '',
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
if (this.config.full) {
|
|
489
|
+
return (0, file_1.writeFile)(this.config.serversPath, fileName, destCode);
|
|
490
|
+
}
|
|
491
|
+
const merger = new merge_1.Merger(mergerProps);
|
|
492
|
+
return (0, file_1.writeFile)(this.config.serversPath, fileName, merger.merge({
|
|
493
|
+
source: destCode,
|
|
494
|
+
}));
|
|
472
495
|
}
|
|
473
496
|
catch (error) {
|
|
474
497
|
console.error('[GenSDK] file gen fail:', fileName, 'type:', type);
|
|
@@ -478,14 +501,18 @@ class ServiceGenerator {
|
|
|
478
501
|
getTemplate(type) {
|
|
479
502
|
return (0, fs_1.readFileSync)((0, path_1.join)(this.config.templatesFolder, `${type}.njk`), 'utf8');
|
|
480
503
|
}
|
|
504
|
+
// 生成方法名 functionName
|
|
481
505
|
getFunctionName(data) {
|
|
482
506
|
// 获取路径相同部分
|
|
483
|
-
const pathBasePrefix = (0,
|
|
507
|
+
const pathBasePrefix = (0, util_2.getBasePrefix)((0, lodash_1.keys)(this.openAPIData.paths));
|
|
484
508
|
return this.config.hook && this.config.hook.customFunctionName
|
|
485
|
-
? this.config.hook.customFunctionName(data)
|
|
486
|
-
: data.
|
|
487
|
-
|
|
488
|
-
|
|
509
|
+
? this.config.hook.customFunctionName(data, pathBasePrefix)
|
|
510
|
+
: (0, util_1.camelCase)(`${(0, util_2.genDefaultFunctionName)(data.path, pathBasePrefix)}-using-${data.method}`);
|
|
511
|
+
// return this.config.hook && this.config.hook.customFunctionName
|
|
512
|
+
// ? this.config.hook.customFunctionName(data)
|
|
513
|
+
// : data.operationId
|
|
514
|
+
// ? resolveFunctionName(stripDot(data.operationId), data.method)
|
|
515
|
+
// : data.method + genDefaultFunctionName(data.path, pathBasePrefix);
|
|
489
516
|
}
|
|
490
517
|
getType(schemaObject, namespace) {
|
|
491
518
|
var _a, _b;
|
|
@@ -496,19 +523,19 @@ class ServiceGenerator {
|
|
|
496
523
|
schemaObject,
|
|
497
524
|
namespace,
|
|
498
525
|
schemas,
|
|
499
|
-
originGetType:
|
|
526
|
+
originGetType: util_2.getDefaultType,
|
|
500
527
|
});
|
|
501
528
|
if (typeof type === 'string') {
|
|
502
529
|
return type;
|
|
503
530
|
}
|
|
504
531
|
}
|
|
505
|
-
return (0,
|
|
532
|
+
return (0, util_2.getDefaultType)(schemaObject, namespace, schemas);
|
|
506
533
|
}
|
|
507
534
|
getFunctionParamsTypeName(data) {
|
|
508
535
|
var _a, _b, _c;
|
|
509
536
|
const namespace = this.config.namespace ? `${this.config.namespace}.` : '';
|
|
510
537
|
const typeName = ((_c = (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.hook) === null || _b === void 0 ? void 0 : _b.customTypeName) === null || _c === void 0 ? void 0 : _c.call(_b, data)) || this.getFunctionName(data);
|
|
511
|
-
return (0,
|
|
538
|
+
return (0, util_2.resolveTypeName)(`${namespace}${typeName !== null && typeName !== void 0 ? typeName : data.operationId}Params`);
|
|
512
539
|
}
|
|
513
540
|
getBodyTP(requestBody) {
|
|
514
541
|
var _a;
|
|
@@ -534,7 +561,7 @@ class ServiceGenerator {
|
|
|
534
561
|
const propertyObj = schema.properties[propertyKey];
|
|
535
562
|
if (propertyObj &&
|
|
536
563
|
![config_1.SchemaObjectFormat.binary, config_1.SchemaObjectFormat.base64].includes(propertyObj.format) &&
|
|
537
|
-
!(0,
|
|
564
|
+
!(0, util_2.isBinaryArraySchemaObject)(propertyObj)) {
|
|
538
565
|
// 测试了很多用例,很少有用例走到这里
|
|
539
566
|
return {
|
|
540
567
|
key: propertyKey,
|
|
@@ -569,7 +596,7 @@ class ServiceGenerator {
|
|
|
569
596
|
const props = (((_a = resolved.props) === null || _a === void 0 ? void 0 : _a.length) > 0 &&
|
|
570
597
|
resolved.props[0].filter((p) => p.format === 'binary' ||
|
|
571
598
|
p.format === 'base64' ||
|
|
572
|
-
(0,
|
|
599
|
+
(0, util_2.isBinaryArraySchemaObject)(p))) ||
|
|
573
600
|
[];
|
|
574
601
|
if (props.length > 0) {
|
|
575
602
|
ret = props.map((p) => {
|
|
@@ -607,10 +634,10 @@ class ServiceGenerator {
|
|
|
607
634
|
}
|
|
608
635
|
let schema = (resContent[mediaType].schema ||
|
|
609
636
|
config_2.DEFAULT_SCHEMA);
|
|
610
|
-
if ((0,
|
|
611
|
-
const refName = (0,
|
|
637
|
+
if ((0, util_2.isReferenceObject)(schema)) {
|
|
638
|
+
const refName = (0, util_2.getLastRefName)(schema.$ref);
|
|
612
639
|
const childrenSchema = components.schemas[refName];
|
|
613
|
-
if ((0,
|
|
640
|
+
if ((0, util_2.isNonArraySchemaObject)(childrenSchema) && this.config.dataFields) {
|
|
614
641
|
schema = (((_a = this.config.dataFields
|
|
615
642
|
.map((field) => childrenSchema.properties[field])
|
|
616
643
|
.filter(Boolean)) === null || _a === void 0 ? void 0 : _a[0]) ||
|
|
@@ -618,7 +645,7 @@ class ServiceGenerator {
|
|
|
618
645
|
config_2.DEFAULT_SCHEMA);
|
|
619
646
|
}
|
|
620
647
|
}
|
|
621
|
-
if ((0,
|
|
648
|
+
if ((0, util_2.isSchemaObject)(schema)) {
|
|
622
649
|
(0, lodash_1.keys)(schema.properties).map((fieldName) => {
|
|
623
650
|
var _a, _b;
|
|
624
651
|
schema.properties[fieldName]['required'] =
|
|
@@ -641,7 +668,7 @@ class ServiceGenerator {
|
|
|
641
668
|
var _a, _b, _c, _d, _e;
|
|
642
669
|
const isDirectObject = (((_a = p.schema) === null || _a === void 0 ? void 0 : _a.type) === 'object' ||
|
|
643
670
|
p.type) === 'object';
|
|
644
|
-
const refName = (0,
|
|
671
|
+
const refName = (0, util_2.getLastRefName)(((_b = p.schema) === null || _b === void 0 ? void 0 : _b.$ref) ||
|
|
645
672
|
p.$ref);
|
|
646
673
|
const deRefObj = (0, lodash_1.entries)((_c = this.openAPIData.components) === null || _c === void 0 ? void 0 : _c.schemas).find(([k]) => k === refName) || [];
|
|
647
674
|
const isRefObject = ((_d = deRefObj[1]) === null || _d === void 0 ? void 0 : _d.type) === 'object' &&
|
|
@@ -672,7 +699,7 @@ class ServiceGenerator {
|
|
|
672
699
|
// 不使用 schemaObject: ISchemaObject = {}
|
|
673
700
|
schemaObject = schemaObject !== null && schemaObject !== void 0 ? schemaObject : {};
|
|
674
701
|
// 引用类型
|
|
675
|
-
if ((0,
|
|
702
|
+
if ((0, util_2.isReferenceObject)(schemaObject)) {
|
|
676
703
|
return this.resolveRefObject(schemaObject);
|
|
677
704
|
}
|
|
678
705
|
// 枚举类型
|
|
@@ -688,15 +715,15 @@ class ServiceGenerator {
|
|
|
688
715
|
return this.resolveProperties(schemaObject);
|
|
689
716
|
}
|
|
690
717
|
// 数组类型
|
|
691
|
-
if ((0,
|
|
718
|
+
if ((0, util_2.isArraySchemaObject)(schemaObject)) {
|
|
692
719
|
return this.resolveArray(schemaObject);
|
|
693
720
|
}
|
|
694
721
|
return schemaObject;
|
|
695
722
|
}
|
|
696
723
|
resolveArray(schemaObject) {
|
|
697
724
|
var _a;
|
|
698
|
-
if ((0,
|
|
699
|
-
const refName = (0,
|
|
725
|
+
if ((0, util_2.isReferenceObject)(schemaObject.items)) {
|
|
726
|
+
const refName = (0, util_2.getRefName)(schemaObject.items);
|
|
700
727
|
return {
|
|
701
728
|
type: `${refName}[]`,
|
|
702
729
|
};
|
|
@@ -719,9 +746,9 @@ class ServiceGenerator {
|
|
|
719
746
|
const enumArray = schemaObject.enum;
|
|
720
747
|
let enumStr = '';
|
|
721
748
|
let enumLabelTypeStr = '';
|
|
722
|
-
if (config_2.numberEnum.includes(schemaObject.type) || (0,
|
|
749
|
+
if (config_2.numberEnum.includes(schemaObject.type) || (0, util_2.isAllNumber)(enumArray)) {
|
|
723
750
|
if (this.config.isSupportParseEnumDesc && schemaObject.description) {
|
|
724
|
-
const enumMap = (0,
|
|
751
|
+
const enumMap = (0, util_2.parseDescriptionEnum)(schemaObject.description);
|
|
725
752
|
enumStr = `{${(0, lodash_1.map)(enumArray, (value) => {
|
|
726
753
|
const enumLabel = enumMap.get(Number(value));
|
|
727
754
|
return `${enumLabel}=${Number(value)}`;
|
|
@@ -731,7 +758,7 @@ class ServiceGenerator {
|
|
|
731
758
|
enumStr = `{${(0, lodash_1.map)(enumArray, (value) => `"NUMBER_${value}"=${Number(value)}`).join(',')}}`;
|
|
732
759
|
}
|
|
733
760
|
}
|
|
734
|
-
else if ((0,
|
|
761
|
+
else if ((0, util_2.isAllNumeric)(enumArray)) {
|
|
735
762
|
enumStr = `{${(0, lodash_1.map)(enumArray, (value) => `"STRING_NUMBER_${value}"="${value}"`).join(',')}}`;
|
|
736
763
|
}
|
|
737
764
|
else {
|
|
@@ -758,9 +785,9 @@ class ServiceGenerator {
|
|
|
758
785
|
}).join(',')}}`;
|
|
759
786
|
}
|
|
760
787
|
else {
|
|
761
|
-
if (config_2.numberEnum.includes(schemaObject.type) || (0,
|
|
788
|
+
if (config_2.numberEnum.includes(schemaObject.type) || (0, util_2.isAllNumber)(enumArray)) {
|
|
762
789
|
if (this.config.isSupportParseEnumDesc && schemaObject.description) {
|
|
763
|
-
const enumMap = (0,
|
|
790
|
+
const enumMap = (0, util_2.parseDescriptionEnum)(schemaObject.description);
|
|
764
791
|
enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => {
|
|
765
792
|
const enumLabel = enumMap.get(Number(value));
|
|
766
793
|
return `${Number(value)}:"${enumLabel}"`;
|
|
@@ -770,7 +797,7 @@ class ServiceGenerator {
|
|
|
770
797
|
enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => `${Number(value)}:"NUMBER_${value}"`).join(',')}}`;
|
|
771
798
|
}
|
|
772
799
|
}
|
|
773
|
-
else if ((0,
|
|
800
|
+
else if ((0, util_2.isAllNumeric)(enumArray)) {
|
|
774
801
|
enumLabelTypeStr = `{${(0, lodash_1.map)(enumArray, (value) => `"${value}":"STRING_NUMBER_${value}"`).join(',')}}`;
|
|
775
802
|
}
|
|
776
803
|
else {
|
|
@@ -785,7 +812,7 @@ class ServiceGenerator {
|
|
|
785
812
|
}
|
|
786
813
|
resolveAllOfObject(schemaObject) {
|
|
787
814
|
const props = (0, lodash_1.map)(schemaObject.allOf, (item) => {
|
|
788
|
-
return (0,
|
|
815
|
+
return (0, util_2.isReferenceObject)(item)
|
|
789
816
|
? [Object.assign(Object.assign({}, item), { type: this.getType(item) })]
|
|
790
817
|
: this.getProps(item);
|
|
791
818
|
});
|
|
@@ -817,16 +844,16 @@ class ServiceGenerator {
|
|
|
817
844
|
});
|
|
818
845
|
}
|
|
819
846
|
resolveRefObject(refObject) {
|
|
820
|
-
if (!(0,
|
|
847
|
+
if (!(0, util_2.isReferenceObject)(refObject)) {
|
|
821
848
|
return refObject;
|
|
822
849
|
}
|
|
823
850
|
const refPaths = refObject.$ref.split('/');
|
|
824
851
|
if (refPaths[0] === '#') {
|
|
825
|
-
const schema = (0,
|
|
852
|
+
const schema = (0, util_2.resolveRefs)(this.openAPIData, refPaths.slice(1));
|
|
826
853
|
if (!schema) {
|
|
827
854
|
throw new Error(`[GenSDK] Data Error! Notfoud: ${refObject.$ref}`);
|
|
828
855
|
}
|
|
829
|
-
return Object.assign(Object.assign({}, (this.resolveRefObject(schema) || {})), { type: (0,
|
|
856
|
+
return Object.assign(Object.assign({}, (this.resolveRefObject(schema) || {})), { type: (0, util_2.isReferenceObject)(schema)
|
|
830
857
|
? this.resolveRefObject(schema).type
|
|
831
858
|
: schema.type });
|
|
832
859
|
}
|
package/dist/generator/type.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ProjectOptions } from 'ts-morph';
|
|
2
|
+
import { type MutuallyExclusive, OperationObject, ParameterObject, SchemaObject } from '../type';
|
|
2
3
|
import { TypescriptFileType } from './config';
|
|
3
4
|
export type ITypescriptFileType = keyof typeof TypescriptFileType;
|
|
4
5
|
export interface APIDataType extends OperationObject {
|
|
@@ -36,3 +37,17 @@ export interface ISchemaItem {
|
|
|
36
37
|
typeName: string;
|
|
37
38
|
type: string;
|
|
38
39
|
}
|
|
40
|
+
export declare enum MergeRule {
|
|
41
|
+
LEFT = "left",
|
|
42
|
+
RIGHT = "right"
|
|
43
|
+
}
|
|
44
|
+
export type MergeOption = MutuallyExclusive<{
|
|
45
|
+
source: string;
|
|
46
|
+
srcPath: string;
|
|
47
|
+
}>;
|
|
48
|
+
type MergerOptionProps = {
|
|
49
|
+
mergeRule: MergeRule;
|
|
50
|
+
projectOptions: ProjectOptions;
|
|
51
|
+
};
|
|
52
|
+
export type MergerOptions = MergeOption & Partial<MergerOptionProps>;
|
|
53
|
+
export {};
|
package/dist/generator/type.js
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MergeRule = void 0;
|
|
4
|
+
var MergeRule;
|
|
5
|
+
(function (MergeRule) {
|
|
6
|
+
MergeRule["LEFT"] = "left";
|
|
7
|
+
MergeRule["RIGHT"] = "right";
|
|
8
|
+
})(MergeRule || (exports.MergeRule = MergeRule = {}));
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { APIDataType } from './generator/type';
|
|
2
|
-
import { ComponentsObject, IPriorityRule, IReactQueryMode, OpenAPIObject, OperationObject, ReferenceObject, SchemaObject } from './type';
|
|
2
|
+
import { ComponentsObject, type GetSchemaByApifoxProps, IPriorityRule, IReactQueryMode, OpenAPIObject, OperationObject, ReferenceObject, SchemaObject } from './type';
|
|
3
3
|
export * from './generator/patchSchema';
|
|
4
4
|
export type GenerateServiceProps = {
|
|
5
5
|
/**
|
|
@@ -17,6 +17,10 @@ export type GenerateServiceProps = {
|
|
|
17
17
|
* 方式二: import request from '@/request';
|
|
18
18
|
*/
|
|
19
19
|
requestLibPath?: string;
|
|
20
|
+
/**
|
|
21
|
+
* 是否全量替换, 默认: true, 如果为false, 则进行增量替换
|
|
22
|
+
*/
|
|
23
|
+
full?: boolean;
|
|
20
24
|
/**
|
|
21
25
|
* 开启日志
|
|
22
26
|
*/
|
|
@@ -93,6 +97,10 @@ export type GenerateServiceProps = {
|
|
|
93
97
|
* 文档权限凭证
|
|
94
98
|
*/
|
|
95
99
|
authorization?: string;
|
|
100
|
+
/**
|
|
101
|
+
* apifox 配置
|
|
102
|
+
*/
|
|
103
|
+
apifoxConfig?: GetSchemaByApifoxProps;
|
|
96
104
|
/**
|
|
97
105
|
* 默认为false,true时使用null代替可选值
|
|
98
106
|
*/
|
|
@@ -121,6 +129,14 @@ export type GenerateServiceProps = {
|
|
|
121
129
|
* 模板文件的文件路径,不需要关注
|
|
122
130
|
*/
|
|
123
131
|
templatesFolder?: string;
|
|
132
|
+
/**
|
|
133
|
+
* 请求超时时间
|
|
134
|
+
*/
|
|
135
|
+
timeout?: number;
|
|
136
|
+
/**
|
|
137
|
+
* 多网关唯一标识
|
|
138
|
+
*/
|
|
139
|
+
uniqueKey?: string;
|
|
124
140
|
/**
|
|
125
141
|
* 自定义 hook
|
|
126
142
|
*/
|
|
@@ -128,7 +144,7 @@ export type GenerateServiceProps = {
|
|
|
128
144
|
/** change open api data after constructor */
|
|
129
145
|
afterOpenApiDataInited?: (openAPIData: OpenAPIObject) => OpenAPIObject;
|
|
130
146
|
/** 自定义函数名称 */
|
|
131
|
-
customFunctionName?: (data: APIDataType) => string;
|
|
147
|
+
customFunctionName?: (data: APIDataType, prefix?: string) => string;
|
|
132
148
|
/** 自定义类型名称 */
|
|
133
149
|
customTypeName?: (data: APIDataType) => string;
|
|
134
150
|
/** 自定义 options 默认值 */
|
|
@@ -180,4 +196,4 @@ export type GenerateServiceProps = {
|
|
|
180
196
|
customFileNames?: (operationObject: OperationObject, apiPath: string, apiMethod: string) => string[] | null;
|
|
181
197
|
};
|
|
182
198
|
};
|
|
183
|
-
export declare function generateService({ requestLibPath, schemaPath, mockFolder, includeTags, excludeTags, authorization, isTranslateToEnglishTag, priorityRule, reactQueryMode, ...rest }: GenerateServiceProps): Promise<void>;
|
|
199
|
+
export declare function generateService({ requestLibPath, schemaPath, mockFolder, includeTags, excludeTags, authorization, isTranslateToEnglishTag, priorityRule, timeout, reactQueryMode, apifoxConfig, ...rest }: GenerateServiceProps): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -10,12 +10,18 @@ const util_1 = require("./util");
|
|
|
10
10
|
tslib_1.__exportStar(require("./generator/patchSchema"), exports);
|
|
11
11
|
function generateService(_a) {
|
|
12
12
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
13
|
-
var { requestLibPath, schemaPath, mockFolder, includeTags, excludeTags, authorization, isTranslateToEnglishTag, priorityRule = config_1.PriorityRule.include, reactQueryMode = config_1.ReactQueryMode.react } = _a, rest = tslib_1.__rest(_a, ["requestLibPath", "schemaPath", "mockFolder", "includeTags", "excludeTags", "authorization", "isTranslateToEnglishTag", "priorityRule", "reactQueryMode"]);
|
|
14
|
-
if (!schemaPath) {
|
|
13
|
+
var { requestLibPath, schemaPath, mockFolder, includeTags, excludeTags, 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", "authorization", "isTranslateToEnglishTag", "priorityRule", "timeout", "reactQueryMode", "apifoxConfig"]);
|
|
14
|
+
if (!schemaPath && !apifoxConfig) {
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
|
-
|
|
18
|
-
if (
|
|
17
|
+
let openAPI = null;
|
|
18
|
+
if (apifoxConfig) {
|
|
19
|
+
openAPI = (yield (0, util_1.getOpenAPIConfigByApifox)(apifoxConfig));
|
|
20
|
+
}
|
|
21
|
+
if (schemaPath) {
|
|
22
|
+
openAPI = (yield (0, util_1.getOpenAPIConfig)(schemaPath, authorization, timeout));
|
|
23
|
+
}
|
|
24
|
+
if (!openAPI || (0, lodash_1.isEmpty)(openAPI)) {
|
|
19
25
|
return;
|
|
20
26
|
}
|
|
21
27
|
if (isTranslateToEnglishTag) {
|
|
@@ -28,7 +34,7 @@ function generateService(_a) {
|
|
|
28
34
|
? [/.*/g]
|
|
29
35
|
: null, excludeTags: excludeTags
|
|
30
36
|
? (0, lodash_1.map)(excludeTags, (item) => typeof item === 'string' ? item.toLowerCase() : item)
|
|
31
|
-
: null, requestOptionsType: '{[key: string]: unknown}', namespace: 'API', isGenReactQuery: false, reactQueryMode, isGenJavaScript: false, isDisplayTypeLabel: false, isGenJsonSchemas: false, nullable: false, isOnlyGenTypeScriptType: false, isCamelCase: true, isSupportParseEnumDesc: false }, rest), openAPI);
|
|
37
|
+
: 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);
|
|
32
38
|
serviceGenerator.genFile();
|
|
33
39
|
if (mockFolder) {
|
|
34
40
|
(0, mockGenarator_1.mockGenerator)({
|
package/dist/log.d.ts
CHANGED
package/dist/log.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.logError = void 0;
|
|
3
4
|
const tslib_1 = require("tslib");
|
|
4
5
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
5
6
|
const log = (...rest) => console.log(`${chalk_1.default.blue('[openAPI]')}: ${rest.join('\n')}`);
|
|
7
|
+
const logError = (...rest) => console.error(`${chalk_1.default.red('❌ [openAPI]')}: ${rest.join('\n')}`);
|
|
8
|
+
exports.logError = logError;
|
|
6
9
|
exports.default = log;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readConfig = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const cosmiconfig_1 = require("cosmiconfig");
|
|
6
|
+
const cosmiconfig_typescript_loader_1 = require("cosmiconfig-typescript-loader");
|
|
7
|
+
const readConfig = (_a) => tslib_1.__awaiter(void 0, [_a], void 0, function* ({ fileName, filePath, fallbackName, }) {
|
|
8
|
+
var _b, _c;
|
|
9
|
+
try {
|
|
10
|
+
let _fileName_ = fileName;
|
|
11
|
+
if (!_fileName_ && !filePath) {
|
|
12
|
+
_fileName_ = fallbackName;
|
|
13
|
+
}
|
|
14
|
+
const explorerSync = (0, cosmiconfig_1.cosmiconfigSync)(_fileName_ || fallbackName, {
|
|
15
|
+
loaders: {
|
|
16
|
+
'.ts': (0, cosmiconfig_typescript_loader_1.TypeScriptLoader)(),
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
if (!_fileName_) {
|
|
20
|
+
return (yield ((_b = explorerSync.load(filePath)) === null || _b === void 0 ? void 0 : _b.config));
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
return (yield ((_c = explorerSync.search()) === null || _c === void 0 ? void 0 : _c.config));
|
|
24
|
+
}
|
|
25
|
+
// eslint-disable-next-line no-unused-vars
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
exports.readConfig = readConfig;
|
package/dist/type.d.ts
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
import { OpenAPIV3 } from 'openapi-types';
|
|
2
2
|
import { PriorityRule, ReactQueryMode, SchemaObjectFormat, SchemaObjectType } from './config';
|
|
3
|
+
export type MutuallyExclusive<T> = {
|
|
4
|
+
[K in keyof T]: {
|
|
5
|
+
[P in K]: T[K];
|
|
6
|
+
} & {
|
|
7
|
+
[P in Exclude<keyof T, K>]?: never;
|
|
8
|
+
};
|
|
9
|
+
}[keyof T];
|
|
10
|
+
export type MutuallyExclusiveWithFallback<T, N> = {
|
|
11
|
+
[K in keyof T]: {
|
|
12
|
+
[P in K]: T[K];
|
|
13
|
+
} & {
|
|
14
|
+
[P in Exclude<keyof T, K>]?: N;
|
|
15
|
+
};
|
|
16
|
+
}[keyof T];
|
|
3
17
|
type Modify<T, R> = Omit<T, keyof R> & R;
|
|
4
18
|
type ICustomBaseSchemaObject = {
|
|
5
19
|
type: ISchemaObjectType;
|
|
@@ -63,4 +77,32 @@ export type GenerateRegExp = {
|
|
|
63
77
|
export type ISchemaObjectType = keyof typeof SchemaObjectType;
|
|
64
78
|
export type IReactQueryMode = keyof typeof ReactQueryMode;
|
|
65
79
|
export type IPriorityRule = keyof typeof PriorityRule;
|
|
80
|
+
export type ReadConfigOptions = MutuallyExclusiveWithFallback<{
|
|
81
|
+
fileName: string;
|
|
82
|
+
filePath: string;
|
|
83
|
+
}, undefined> & {
|
|
84
|
+
fallbackName: string;
|
|
85
|
+
};
|
|
86
|
+
export interface APIFoxBody {
|
|
87
|
+
scope: {
|
|
88
|
+
type?: 'ALL' | 'SELECTED_TAGS';
|
|
89
|
+
includeTags?: string[];
|
|
90
|
+
excludeTags?: string[];
|
|
91
|
+
};
|
|
92
|
+
options?: {
|
|
93
|
+
includeApifoxExtensionProperties: boolean;
|
|
94
|
+
addFoldersToTags: boolean;
|
|
95
|
+
};
|
|
96
|
+
oasVersion?: '2.0' | '3.0' | '3.1';
|
|
97
|
+
exportFormat?: 'JSON' | 'YAML';
|
|
98
|
+
environmentIds?: string[];
|
|
99
|
+
}
|
|
100
|
+
export interface GetSchemaByApifoxProps {
|
|
101
|
+
projectId: string;
|
|
102
|
+
locale?: string;
|
|
103
|
+
apifoxVersion?: string;
|
|
104
|
+
includeTags?: (string | RegExp)[];
|
|
105
|
+
excludeTags?: string[];
|
|
106
|
+
apifoxToken: string;
|
|
107
|
+
}
|
|
66
108
|
export {};
|
package/dist/util.d.ts
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import { OpenAPI } from 'openapi-types';
|
|
2
|
-
import { OpenAPIObject } from './type';
|
|
2
|
+
import { type GetSchemaByApifoxProps, OpenAPIObject } from './type';
|
|
3
3
|
export declare const getImportStatement: (requestLibPath: string) => string;
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const getOpenAPIConfigByApifox: (props: GetSchemaByApifoxProps) => Promise<OpenAPI.Document<{}>>;
|
|
5
|
+
export declare const getOpenAPIConfig: (schemaPath: string, authorization?: string, timeout?: number) => Promise<OpenAPI.Document<{}>>;
|
|
5
6
|
export declare function parseSwaggerOrOpenapi(content: string | OpenAPI.Document): Promise<OpenAPI.Document<{}>>;
|
|
6
7
|
export declare function translateChineseModuleNodeToEnglish(openAPI: OpenAPIObject): Promise<unknown>;
|
|
8
|
+
/**
|
|
9
|
+
* Converts a string to camelCase format, with an option to capitalize the first letter.
|
|
10
|
+
* 将字符串转换为驼峰格式,并可以选择将首字母大写。
|
|
11
|
+
*
|
|
12
|
+
* @param {string} str - The string to convert.
|
|
13
|
+
* @param {string} str - 要转换的字符串。
|
|
14
|
+
*
|
|
15
|
+
* @param {boolean} [upper=false] - Whether to capitalize the first letter of the resulting string.
|
|
16
|
+
* @param {boolean} [upper=false] - 是否将结果字符串的首字母大写。
|
|
17
|
+
*
|
|
18
|
+
* @returns {string} The camelCase formatted string, optionally with a capitalized first letter.
|
|
19
|
+
* @returns {string} 返回驼峰格式的字符串,可选择首字母大写。
|
|
20
|
+
*/
|
|
21
|
+
export declare const camelCase: (str: string, upper?: boolean) => string;
|