wormajs 0.0.2-beta.3 → 0.1.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/dist/constant.js +6 -1
- package/dist/plugins/index.js +6 -2
- package/dist/plugins/presets/platform/fastapi.js +22 -0
- package/dist/plugins/presets/platform/index.js +15 -0
- package/dist/plugins/presets/platform/knife4j.js +24 -0
- package/dist/plugins/presets/platform/shared.js +45 -0
- package/dist/plugins/presets/platform/swagger.js +32 -0
- package/dist/plugins/presets/platform/yapi.js +75 -0
- package/dist/plugins/presets/rename.js +149 -21
- package/dist/plugins/presets/utils.js +11 -10
- package/dist/template/index.js +0 -34
- package/dist/template/presets/alova/partials/dts-extra-config.handlebars +3 -3
- package/dist/template/presets/alova/partials/dts-fn-declare.handlebars +1 -1
- package/dist/template/presets/alova/typescript/services/{tag}.ts.handlebars +5 -5
- package/dist/template/presets/axios/partials/dts-types.handlebars +4 -4
- package/dist/template/presets/axios/typescript/services/{tag}.ts.handlebars +4 -4
- package/dist/template/presets/config/common/worma.config.js.handlebars +1 -1
- package/dist/template/presets/config/module/worma.config.js.handlebars +1 -1
- package/dist/template/presets/config/partials/generator-content.handlebars +45 -45
- package/dist/template/presets/config/typescript/worma.config.ts.handlebars +1 -1
- package/dist/template/presets/fetch/partials/dts-types.handlebars +4 -4
- package/dist/template/presets/fetch/typescript/services/{tag}.ts.handlebars +4 -4
- package/dist/template/presets/ky/partials/dts-types.handlebars +4 -4
- package/dist/template/presets/ky/typescript/services/{tag}.ts.handlebars +4 -4
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/template.js +23 -0
- package/package.json +1 -1
- package/typings/plugins.d.ts +87 -14
- package/dist/plugins/presets/platform.js +0 -73
package/dist/constant.js
CHANGED
|
@@ -26,6 +26,7 @@ var PlatformTypeEnum;
|
|
|
26
26
|
(function (PlatformTypeEnum) {
|
|
27
27
|
PlatformTypeEnum["SWAGGER"] = "swagger";
|
|
28
28
|
PlatformTypeEnum["KNIFE4J"] = "knife4j";
|
|
29
|
+
PlatformTypeEnum["FASTAPI"] = "fastapi";
|
|
29
30
|
PlatformTypeEnum["YAPI"] = "yapi";
|
|
30
31
|
})(PlatformTypeEnum || (exports.PlatformTypeEnum = PlatformTypeEnum = {}));
|
|
31
32
|
/** 模块体系类型 */
|
|
@@ -77,6 +78,7 @@ var RenameScope;
|
|
|
77
78
|
RenameScope["DATA"] = "data";
|
|
78
79
|
RenameScope["RESPONSE"] = "response";
|
|
79
80
|
RenameScope["REF_NAME"] = "refName";
|
|
81
|
+
RenameScope["NAME"] = "name";
|
|
80
82
|
})(RenameScope || (exports.RenameScope = RenameScope = {}));
|
|
81
83
|
/** 过滤 scope 类型 */
|
|
82
84
|
var FilterScope;
|
|
@@ -102,7 +104,10 @@ var PluginName;
|
|
|
102
104
|
PluginName["IMPORT_TYPE"] = "importType";
|
|
103
105
|
PluginName["AI_DOC"] = "aiDoc";
|
|
104
106
|
PluginName["APIFOX"] = "apifox";
|
|
105
|
-
PluginName["
|
|
107
|
+
PluginName["SWAGGER"] = "swagger";
|
|
108
|
+
PluginName["KNIFE4J"] = "knife4j";
|
|
109
|
+
PluginName["FASTAPI"] = "fastapi";
|
|
110
|
+
PluginName["YAPI"] = "yapi";
|
|
106
111
|
PluginName["TEMPLATE_ALOVA"] = "templateAlova";
|
|
107
112
|
PluginName["TEMPLATE_ALOVA_GLOBALS"] = "templateAlovaGlobals";
|
|
108
113
|
PluginName["TEMPLATE_AXIOS"] = "templateAxios";
|
package/dist/plugins/index.js
CHANGED
|
@@ -14,14 +14,18 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.ky = exports.config = exports.axios = exports.alovaGlobals = exports.alova = void 0;
|
|
17
|
+
exports.ky = exports.config = exports.axios = exports.alovaGlobals = exports.alova = exports.yapi = exports.swagger = exports.knife4j = exports.fastapi = void 0;
|
|
18
18
|
__exportStar(require("./createPlugin"), exports);
|
|
19
19
|
__exportStar(require("./presets/aiDoc"), exports);
|
|
20
20
|
__exportStar(require("./presets/apifox"), exports);
|
|
21
21
|
__exportStar(require("./presets/filterApi"), exports);
|
|
22
22
|
__exportStar(require("./presets/importType"), exports);
|
|
23
23
|
__exportStar(require("./presets/payloadModifier"), exports);
|
|
24
|
-
|
|
24
|
+
var platform_1 = require("./presets/platform");
|
|
25
|
+
Object.defineProperty(exports, "fastapi", { enumerable: true, get: function () { return platform_1.fastapi; } });
|
|
26
|
+
Object.defineProperty(exports, "knife4j", { enumerable: true, get: function () { return platform_1.knife4j; } });
|
|
27
|
+
Object.defineProperty(exports, "swagger", { enumerable: true, get: function () { return platform_1.swagger; } });
|
|
28
|
+
Object.defineProperty(exports, "yapi", { enumerable: true, get: function () { return platform_1.yapi; } });
|
|
25
29
|
__exportStar(require("./presets/rename"), exports);
|
|
26
30
|
__exportStar(require("./presets/tagModifier"), exports);
|
|
27
31
|
// Template preset plugins
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fastapi = void 0;
|
|
4
|
+
const constant_1 = require("../../../constant");
|
|
5
|
+
const shared_1 = require("./shared");
|
|
6
|
+
/**
|
|
7
|
+
* FastAPI platform plugin.
|
|
8
|
+
*
|
|
9
|
+
* Pass the base URL of your FastAPI app; the plugin will try `/openapi.json`
|
|
10
|
+
* first, then fall back to the bare base URL.
|
|
11
|
+
*
|
|
12
|
+
* @param input - base URL string, or an array of base URLs
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* plugins: [fastapi('http://fastapi-example.dokkuapp.com'), alovaGlobals()]
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
exports.fastapi = (0, shared_1.defineUrlPlatformPlugin)(constant_1.PluginName.FASTAPI, base => [
|
|
20
|
+
`${base}/openapi.json`,
|
|
21
|
+
base,
|
|
22
|
+
]);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.yapi = exports.swagger = exports.withCookie = exports.normalizeBase = exports.defineUrlPlatformPlugin = exports.knife4j = exports.fastapi = void 0;
|
|
4
|
+
var fastapi_1 = require("./fastapi");
|
|
5
|
+
Object.defineProperty(exports, "fastapi", { enumerable: true, get: function () { return fastapi_1.fastapi; } });
|
|
6
|
+
var knife4j_1 = require("./knife4j");
|
|
7
|
+
Object.defineProperty(exports, "knife4j", { enumerable: true, get: function () { return knife4j_1.knife4j; } });
|
|
8
|
+
var shared_1 = require("./shared");
|
|
9
|
+
Object.defineProperty(exports, "defineUrlPlatformPlugin", { enumerable: true, get: function () { return shared_1.defineUrlPlatformPlugin; } });
|
|
10
|
+
Object.defineProperty(exports, "normalizeBase", { enumerable: true, get: function () { return shared_1.normalizeBase; } });
|
|
11
|
+
Object.defineProperty(exports, "withCookie", { enumerable: true, get: function () { return shared_1.withCookie; } });
|
|
12
|
+
var swagger_1 = require("./swagger");
|
|
13
|
+
Object.defineProperty(exports, "swagger", { enumerable: true, get: function () { return swagger_1.swagger; } });
|
|
14
|
+
var yapi_1 = require("./yapi");
|
|
15
|
+
Object.defineProperty(exports, "yapi", { enumerable: true, get: function () { return yapi_1.yapi; } });
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.knife4j = void 0;
|
|
4
|
+
const constant_1 = require("../../../constant");
|
|
5
|
+
const shared_1 = require("./shared");
|
|
6
|
+
/**
|
|
7
|
+
* Knife4j platform plugin.
|
|
8
|
+
*
|
|
9
|
+
* Pass the base URL of your Knife4j instance; the plugin will try the OAS3
|
|
10
|
+
* endpoint (springdoc) first, then the Swagger2 endpoint (springfox), then the
|
|
11
|
+
* bare base URL.
|
|
12
|
+
*
|
|
13
|
+
* @param input - base URL string, or an array of base URLs
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* plugins: [knife4j('https://openapi3.demo.knife4jnext.com'), alovaGlobals()]
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
exports.knife4j = (0, shared_1.defineUrlPlatformPlugin)(constant_1.PluginName.KNIFE4J, base => [
|
|
21
|
+
`${base}/v3/api-docs`,
|
|
22
|
+
`${base}/v2/api-docs`,
|
|
23
|
+
base,
|
|
24
|
+
]);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeBase = normalizeBase;
|
|
4
|
+
exports.defineUrlPlatformPlugin = defineUrlPlatformPlugin;
|
|
5
|
+
exports.withCookie = withCookie;
|
|
6
|
+
/** Remove trailing slashes from a base URL */
|
|
7
|
+
function normalizeBase(baseUrl) {
|
|
8
|
+
while (baseUrl.endsWith('/')) {
|
|
9
|
+
baseUrl = baseUrl.slice(0, -1);
|
|
10
|
+
}
|
|
11
|
+
return baseUrl;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Factory for "URL-constructing" platform plugins.
|
|
15
|
+
*
|
|
16
|
+
* Unlike the old `platform()` helper, the platform base URL(s) are supplied as
|
|
17
|
+
* the plugin's own argument (e.g. `swagger('https://petstore.swagger.io')`)
|
|
18
|
+
* rather than being read from `config.input`. The plugin writes the resolved
|
|
19
|
+
* candidate URLs into `config.input` inside its `config` hook, so downstream
|
|
20
|
+
* fetching (which tries each URL in order and keeps the first success) works
|
|
21
|
+
* unchanged.
|
|
22
|
+
*/
|
|
23
|
+
function defineUrlPlatformPlugin(name, buildUrls) {
|
|
24
|
+
return (input) => {
|
|
25
|
+
const inputs = Array.isArray(input) ? [...new Set(input)] : [input];
|
|
26
|
+
return {
|
|
27
|
+
name,
|
|
28
|
+
config({ config }) {
|
|
29
|
+
config.input = inputs.flatMap(url => buildUrls(normalizeBase(String(url))));
|
|
30
|
+
return config;
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** Merge a cookie into config.fetchOptions.headers */
|
|
36
|
+
function withCookie(config, cookie) {
|
|
37
|
+
config.fetchOptions = {
|
|
38
|
+
...config.fetchOptions,
|
|
39
|
+
headers: {
|
|
40
|
+
...config.fetchOptions?.headers,
|
|
41
|
+
cookie,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
return config;
|
|
45
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.swagger = void 0;
|
|
4
|
+
const constant_1 = require("../../../constant");
|
|
5
|
+
const shared_1 = require("./shared");
|
|
6
|
+
/**
|
|
7
|
+
* Swagger platform plugin.
|
|
8
|
+
*
|
|
9
|
+
* Pass the base URL of your Swagger UI / server; the plugin will try several
|
|
10
|
+
* common OpenAPI document endpoints (OAS3 first, then Swagger2, then the bare
|
|
11
|
+
* base URL) and let the framework pick the first one that responds.
|
|
12
|
+
*
|
|
13
|
+
* @param input - base URL string, or an array of base URLs
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { swagger, alovaGlobals } from 'wormajs/plugin';
|
|
18
|
+
*
|
|
19
|
+
* defineConfig({
|
|
20
|
+
* generator: [{
|
|
21
|
+
* plugins: [swagger('https://petstore3.swagger.io'), alovaGlobals()],
|
|
22
|
+
* output: './src/api',
|
|
23
|
+
* }]
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
exports.swagger = (0, shared_1.defineUrlPlatformPlugin)(constant_1.PluginName.SWAGGER, base => [
|
|
28
|
+
`${base}/openapi.json`,
|
|
29
|
+
`${base}/v2/swagger.json`,
|
|
30
|
+
`${base}/api/v3/openapi.json`,
|
|
31
|
+
base,
|
|
32
|
+
]);
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.yapi = yapi;
|
|
4
|
+
const constant_1 = require("../../../constant");
|
|
5
|
+
const shared_1 = require("./shared");
|
|
6
|
+
/**
|
|
7
|
+
* YApi platform plugin.
|
|
8
|
+
*
|
|
9
|
+
* YApi projects are private, so the OpenAPI document must be exported through
|
|
10
|
+
* YApi's own export endpoint, authenticated with your login cookie. The plugin
|
|
11
|
+
* builds the export URL from the server base URL (`url`) plus the required
|
|
12
|
+
* `pid` and the optional `type` / `status` / `isWiki` query params (which
|
|
13
|
+
* default to `OpenAPIV2`, `all`, and `true` respectively).
|
|
14
|
+
*
|
|
15
|
+
* `url`, `pid` and `cookie` are required — the plugin throws a clear error when
|
|
16
|
+
* any is missing.
|
|
17
|
+
*
|
|
18
|
+
* @param options - `{ url, pid, cookie?, type?, status?, isWiki?, timeout? }`
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { yapi, alovaGlobals } from 'wormajs/plugin';
|
|
23
|
+
*
|
|
24
|
+
* defineConfig({
|
|
25
|
+
* generator: [{
|
|
26
|
+
* plugins: [
|
|
27
|
+
* yapi({
|
|
28
|
+
* url: 'https://yapi.xxx.com',
|
|
29
|
+
* pid: 123,
|
|
30
|
+
* cookie: '_yapi_token=xxx; _yapi_uid=yyy',
|
|
31
|
+
* }),
|
|
32
|
+
* alovaGlobals(),
|
|
33
|
+
* ],
|
|
34
|
+
* output: './src/api',
|
|
35
|
+
* }]
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
function yapi(options) {
|
|
40
|
+
return {
|
|
41
|
+
name: constant_1.PluginName.YAPI,
|
|
42
|
+
async config({ config }) {
|
|
43
|
+
const baseUrl = options.url;
|
|
44
|
+
if (!baseUrl) {
|
|
45
|
+
throw new Error('[yapi] `url` is required — the YApi server base URL '
|
|
46
|
+
+ '(e.g. yapi({ url: "https://yapi.xxx.com", pid: 123, cookie: "..." })).');
|
|
47
|
+
}
|
|
48
|
+
const pid = options.pid;
|
|
49
|
+
if (pid == null) {
|
|
50
|
+
throw new Error('[yapi] `pid` is required — the YApi project id used to build the export URL '
|
|
51
|
+
+ '(e.g. yapi({ url: "https://yapi.xxx.com", pid: 123, cookie: "..." })).');
|
|
52
|
+
}
|
|
53
|
+
const cookie = options.cookie ?? config.fetchOptions?.headers?.cookie;
|
|
54
|
+
if (!cookie) {
|
|
55
|
+
throw new Error('[yapi] `cookie` is required. YApi projects are private, so the export '
|
|
56
|
+
+ 'endpoint needs your login cookie to fetch the OpenAPI document.\n'
|
|
57
|
+
+ ' e.g. yapi({ url: "https://yapi.xxx.com", pid: 123, cookie: "_yapi_token=xxx; ..." })');
|
|
58
|
+
}
|
|
59
|
+
const type = options.type ?? 'OpenAPIV2';
|
|
60
|
+
const status = options.status ?? 'all';
|
|
61
|
+
const isWiki = options.isWiki ?? true;
|
|
62
|
+
const base = (0, shared_1.normalizeBase)(baseUrl);
|
|
63
|
+
config.input = `${base}/api/plugin/exportSwagger`
|
|
64
|
+
+ `?type=${encodeURIComponent(type)}`
|
|
65
|
+
+ `&pid=${encodeURIComponent(String(pid))}`
|
|
66
|
+
+ `&status=${encodeURIComponent(status)}`
|
|
67
|
+
+ `&isWiki=${isWiki}`;
|
|
68
|
+
(0, shared_1.withCookie)(config, cookie);
|
|
69
|
+
if (options.timeout != null) {
|
|
70
|
+
config.fetchOptions = { ...config.fetchOptions, timeout: options.timeout };
|
|
71
|
+
}
|
|
72
|
+
return config;
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
@@ -27,8 +27,12 @@ function toPascalCase(str) {
|
|
|
27
27
|
* Applies renaming rules to the specified value
|
|
28
28
|
* @returns The renamed value, or original value if not matched
|
|
29
29
|
*/
|
|
30
|
-
function applyRenameRule(value, config, apiDescriptor) {
|
|
31
|
-
|
|
30
|
+
function applyRenameRule(value, config, apiDescriptor, level = 0) {
|
|
31
|
+
// Skip non-string values (e.g. a missing or empty operationId) to avoid runtime errors
|
|
32
|
+
if (typeof value !== 'string') {
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
if (!(0, utils_1.isMatch)(value, config.match, level)) {
|
|
32
36
|
return value;
|
|
33
37
|
}
|
|
34
38
|
if (config.transform) {
|
|
@@ -38,7 +42,7 @@ function applyRenameRule(value, config, apiDescriptor) {
|
|
|
38
42
|
return value;
|
|
39
43
|
}
|
|
40
44
|
if (config.style === 'kebabCase' && config.scope === 'refName') {
|
|
41
|
-
throw new Error(`Invalid rename style: ${config.style}
|
|
45
|
+
throw new Error(`Invalid rename style: ${config.style}, ${config.scope}`);
|
|
42
46
|
}
|
|
43
47
|
switch (config.style) {
|
|
44
48
|
case 'camelCase':
|
|
@@ -53,6 +57,59 @@ function applyRenameRule(value, config, apiDescriptor) {
|
|
|
53
57
|
throw new Error(`Invalid rename style: ${config.style}`);
|
|
54
58
|
}
|
|
55
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Validates that no duplicate names exist after renaming.
|
|
62
|
+
* Throws an error with details if duplicates are found within the same scope.
|
|
63
|
+
*
|
|
64
|
+
* @param names the renamed names to check for duplicates
|
|
65
|
+
* @param scopeLabel used to identify the scope in the error message
|
|
66
|
+
* @param apiDescriptor the API descriptor the names belong to
|
|
67
|
+
* @param originalNames optional, the original keys before renaming (same order
|
|
68
|
+
* as `names`). When provided, the error message also lists which original keys
|
|
69
|
+
* were mapped to each duplicated name, making the conflict easier to locate.
|
|
70
|
+
*/
|
|
71
|
+
function assertNoDuplicates(names, scopeLabel, apiDescriptor, originalNames) {
|
|
72
|
+
if (!names || names.length === 0)
|
|
73
|
+
return;
|
|
74
|
+
const counts = new Map();
|
|
75
|
+
for (const name of names) {
|
|
76
|
+
counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
77
|
+
}
|
|
78
|
+
const duplicates = [...counts.entries()]
|
|
79
|
+
.filter(([, count]) => count > 1)
|
|
80
|
+
.map(([name]) => name);
|
|
81
|
+
if (duplicates.length === 0)
|
|
82
|
+
return;
|
|
83
|
+
// When original keys are available, group them by the duplicated (renamed) name
|
|
84
|
+
// so users can see exactly which keys collided.
|
|
85
|
+
let detail = '';
|
|
86
|
+
if (originalNames && originalNames.length === names.length) {
|
|
87
|
+
const grouped = new Map();
|
|
88
|
+
for (let i = 0; i < names.length; i++) {
|
|
89
|
+
if (duplicates.includes(names[i])) {
|
|
90
|
+
const list = grouped.get(names[i]) ?? [];
|
|
91
|
+
list.push(originalNames[i]);
|
|
92
|
+
grouped.set(names[i], list);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
detail = [...grouped.entries()]
|
|
96
|
+
.map(([renamed, originals]) => ` ${renamed} <- [${originals.join(', ')}]`)
|
|
97
|
+
.join('\n');
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
detail = ` ${duplicates.join(', ')}`;
|
|
101
|
+
}
|
|
102
|
+
const method = apiDescriptor.method ? String(apiDescriptor.method).toUpperCase() : '';
|
|
103
|
+
const url = apiDescriptor.url ?? '';
|
|
104
|
+
throw new Error(`[rename] Duplicate names found after renaming (scope=${scopeLabel}):\n`
|
|
105
|
+
+ ` Conflicting (renamed) keys and their original keys:\n`
|
|
106
|
+
+ `${detail}\n`
|
|
107
|
+
+ ` Reason: different original names were mapped to the same name after `
|
|
108
|
+
+ `match/transform/style processing, which would cause naming conflicts or `
|
|
109
|
+
+ `missing references in the generated code.\n`
|
|
110
|
+
+ ` Please adjust the rename config to avoid mapping multiple names to the same result.\n`
|
|
111
|
+
+ ` API: ${method} ${url}`);
|
|
112
|
+
}
|
|
56
113
|
/**
|
|
57
114
|
* renames URL path by processing each segment individually
|
|
58
115
|
* while keeping path parameter placeholders
|
|
@@ -65,27 +122,72 @@ function renameUrl(url, config, apiDescriptor) {
|
|
|
65
122
|
if ((segment.startsWith('{') && segment.endsWith('}')) || !segment) {
|
|
66
123
|
return segment;
|
|
67
124
|
}
|
|
68
|
-
return applyRenameRule(segment, config, apiDescriptor);
|
|
125
|
+
return applyRenameRule(segment, config, apiDescriptor, 0);
|
|
69
126
|
})
|
|
70
127
|
.join('/')
|
|
71
128
|
.replace(/^\/{2,}/g, '/');
|
|
72
129
|
}
|
|
73
130
|
/**
|
|
74
|
-
*
|
|
131
|
+
* Recursively processes a schema (supports nested objects and arrays),
|
|
132
|
+
* applying property renaming to nested objects.
|
|
133
|
+
* @param schema current schema
|
|
134
|
+
* @param level current nesting level (starts from 0)
|
|
135
|
+
* @param scopeLabel used to identify the scope in duplicate-name errors
|
|
136
|
+
*/
|
|
137
|
+
function transformSchema(schema, config, apiDescriptor, level, scopeLabel) {
|
|
138
|
+
if (!schema || typeof schema !== 'object')
|
|
139
|
+
return schema;
|
|
140
|
+
// Nested object: recursively process its properties
|
|
141
|
+
if ('properties' in schema && schema.properties) {
|
|
142
|
+
return transformProperties(schema, config, apiDescriptor, level, scopeLabel);
|
|
143
|
+
}
|
|
144
|
+
// Array: recursively process items (supports a single schema or an array of schemas)
|
|
145
|
+
if (schema.items && typeof schema.items === 'object') {
|
|
146
|
+
if (Array.isArray(schema.items)) {
|
|
147
|
+
return {
|
|
148
|
+
...schema,
|
|
149
|
+
items: schema.items.map((item) => transformSchema(item, config, apiDescriptor, level, scopeLabel)),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
...schema,
|
|
154
|
+
items: transformSchema(schema.items, config, apiDescriptor, level, scopeLabel),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
return schema;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Transforms object properties using the renaming rules (supports deep recursive renaming)
|
|
161
|
+
* @param level current nesting level (starts from 0), passed through to the match function
|
|
162
|
+
* @param scopeLabel used to identify the scope in duplicate-name errors
|
|
75
163
|
*/
|
|
76
|
-
function transformProperties(obj, config, apiDescriptor) {
|
|
77
|
-
if (!obj || typeof obj !== 'object' || !('properties' in obj)) {
|
|
164
|
+
function transformProperties(obj, config, apiDescriptor, level = 0, scopeLabel = config.scope ?? 'data') {
|
|
165
|
+
if (!obj || typeof obj !== 'object' || !('properties' in obj) || !obj.properties) {
|
|
78
166
|
return obj;
|
|
79
167
|
}
|
|
80
|
-
const properties =
|
|
168
|
+
const properties = obj.properties;
|
|
81
169
|
const newProperties = {};
|
|
170
|
+
const newKeys = [];
|
|
171
|
+
// Record the oldKey -> newKey mapping, used to keep the same-level required array in sync
|
|
172
|
+
const keyMap = new Map();
|
|
82
173
|
for (const key in properties) {
|
|
83
|
-
const newKey = applyRenameRule(key, config, apiDescriptor);
|
|
84
|
-
|
|
174
|
+
const newKey = applyRenameRule(key, config, apiDescriptor, level);
|
|
175
|
+
newKeys.push(newKey);
|
|
176
|
+
keyMap.set(key, newKey);
|
|
177
|
+
newProperties[newKey] = transformSchema(properties[key], config, apiDescriptor, level + 1, scopeLabel);
|
|
178
|
+
}
|
|
179
|
+
// Duplicate property names within the same object level would overwrite each other, so report an error
|
|
180
|
+
assertNoDuplicates(newKeys, scopeLabel, apiDescriptor, Object.keys(properties));
|
|
181
|
+
// Keep the required array of the current level in sync with the renamed property names;
|
|
182
|
+
// otherwise the generator would crash during normalization because required references a non-existent property
|
|
183
|
+
let newRequired = obj.required;
|
|
184
|
+
if (Array.isArray(newRequired)) {
|
|
185
|
+
newRequired = newRequired.map((r) => keyMap.get(r) ?? r);
|
|
85
186
|
}
|
|
86
187
|
return {
|
|
87
188
|
...obj,
|
|
88
189
|
properties: newProperties,
|
|
190
|
+
...(newRequired !== obj.required ? { required: newRequired } : {}),
|
|
89
191
|
};
|
|
90
192
|
}
|
|
91
193
|
/**
|
|
@@ -99,7 +201,7 @@ function transformParameters(parameters, type, config, apiDescriptor) {
|
|
|
99
201
|
if (param.in === type) {
|
|
100
202
|
return {
|
|
101
203
|
...param,
|
|
102
|
-
name: applyRenameRule(param.name, config, apiDescriptor),
|
|
204
|
+
name: applyRenameRule(param.name, config, apiDescriptor, 0),
|
|
103
205
|
};
|
|
104
206
|
}
|
|
105
207
|
return param;
|
|
@@ -110,10 +212,14 @@ function transformRefNameMap(refNameMap, config, apiDescriptor) {
|
|
|
110
212
|
return refNameMap;
|
|
111
213
|
}
|
|
112
214
|
const newRefNameMap = {};
|
|
215
|
+
const newValues = [];
|
|
113
216
|
for (const key in refNameMap) {
|
|
114
|
-
const newValue = applyRenameRule(refNameMap[key], config, apiDescriptor);
|
|
217
|
+
const newValue = applyRenameRule(refNameMap[key], config, apiDescriptor, 0);
|
|
218
|
+
newValues.push(newValue);
|
|
115
219
|
newRefNameMap[key] = newValue;
|
|
116
220
|
}
|
|
221
|
+
// Different $refs mapping to the same type name would generate duplicate interfaces, so report an error
|
|
222
|
+
assertNoDuplicates(newValues, 'refName', apiDescriptor, Object.keys(refNameMap));
|
|
117
223
|
return newRefNameMap;
|
|
118
224
|
}
|
|
119
225
|
/**
|
|
@@ -125,6 +231,7 @@ function transformRefNameMap(refNameMap, config, apiDescriptor) {
|
|
|
125
231
|
* - pathParams: Renames path parameters and their placeholders in URL
|
|
126
232
|
* - data: Renames request body properties
|
|
127
233
|
* - response: Renames response body properties
|
|
234
|
+
* - name: Renames the generated API function name (operationId)
|
|
128
235
|
*/
|
|
129
236
|
function renameApiDescriptor(apiDescriptor, config) {
|
|
130
237
|
if (!apiDescriptor)
|
|
@@ -134,33 +241,49 @@ function renameApiDescriptor(apiDescriptor, config) {
|
|
|
134
241
|
switch (scope) {
|
|
135
242
|
case constant_1.RenameScope.PARAMS:
|
|
136
243
|
if (newDescriptor.parameters) {
|
|
244
|
+
const originalParams = newDescriptor.parameters.filter(p => p.in === constant_1.ParameterIn.QUERY).map(p => p.name);
|
|
137
245
|
newDescriptor.parameters = transformParameters(newDescriptor.parameters, constant_1.ParameterIn.QUERY, config, apiDescriptor);
|
|
246
|
+
// Duplicate query parameter names would be indistinguishable when calling the API, so report an error
|
|
247
|
+
assertNoDuplicates(newDescriptor.parameters.filter(p => p.in === constant_1.ParameterIn.QUERY).map(p => p.name), 'params', apiDescriptor, originalParams);
|
|
138
248
|
}
|
|
139
249
|
break;
|
|
140
250
|
case constant_1.RenameScope.PATH_PARAMS:
|
|
141
251
|
if (newDescriptor.parameters) {
|
|
252
|
+
const originalParams = newDescriptor.parameters.filter(p => p.in === constant_1.ParameterIn.PATH).map(p => p.name);
|
|
142
253
|
newDescriptor.parameters = transformParameters(newDescriptor.parameters, constant_1.ParameterIn.PATH, config, apiDescriptor);
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
254
|
+
if (newDescriptor.url) {
|
|
255
|
+
newDescriptor.url = newDescriptor.url.replace(/\{([^}]+)\}/g, (match, paramName) => {
|
|
256
|
+
const newName = applyRenameRule(paramName, config, apiDescriptor, 0);
|
|
257
|
+
return `{${newName}}`;
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
// Duplicate path parameter names would make URL placeholders no longer match the parameters, so report an error
|
|
261
|
+
assertNoDuplicates((newDescriptor.parameters ?? []).filter(p => p.in === constant_1.ParameterIn.PATH).map(p => p.name), 'pathParams', apiDescriptor, originalParams);
|
|
149
262
|
}
|
|
150
263
|
break;
|
|
151
264
|
case constant_1.RenameScope.DATA:
|
|
152
265
|
if (newDescriptor.requestBody) {
|
|
153
|
-
newDescriptor.requestBody = transformProperties(newDescriptor.requestBody, config, apiDescriptor);
|
|
266
|
+
newDescriptor.requestBody = transformProperties(newDescriptor.requestBody, config, apiDescriptor, 0, 'data');
|
|
154
267
|
}
|
|
155
268
|
break;
|
|
156
269
|
case constant_1.RenameScope.RESPONSE:
|
|
157
270
|
if (newDescriptor.responses) {
|
|
158
|
-
newDescriptor.responses = transformProperties(newDescriptor.responses, config, apiDescriptor);
|
|
271
|
+
newDescriptor.responses = transformProperties(newDescriptor.responses, config, apiDescriptor, 0, 'response');
|
|
159
272
|
}
|
|
160
273
|
break;
|
|
161
274
|
case constant_1.RenameScope.URL:
|
|
162
275
|
if (newDescriptor.url) {
|
|
276
|
+
const originalUrlNames = newDescriptor.url
|
|
277
|
+
.split('/')
|
|
278
|
+
.filter(Boolean)
|
|
279
|
+
.map(segment => (segment.startsWith('{') && segment.endsWith('}') ? segment.slice(1, -1) : segment));
|
|
163
280
|
newDescriptor.url = renameUrl(newDescriptor.url, config, apiDescriptor);
|
|
281
|
+
// Duplicate path segments would make the URL unable to distinguish different resources, so report an error
|
|
282
|
+
const urlNames = newDescriptor.url
|
|
283
|
+
.split('/')
|
|
284
|
+
.filter(Boolean)
|
|
285
|
+
.map(segment => (segment.startsWith('{') && segment.endsWith('}') ? segment.slice(1, -1) : segment));
|
|
286
|
+
assertNoDuplicates(urlNames, 'url', apiDescriptor, originalUrlNames);
|
|
164
287
|
}
|
|
165
288
|
break;
|
|
166
289
|
case constant_1.RenameScope.REF_NAME:
|
|
@@ -168,6 +291,11 @@ function renameApiDescriptor(apiDescriptor, config) {
|
|
|
168
291
|
newDescriptor.refNameMap = transformRefNameMap(newDescriptor.refNameMap, config, apiDescriptor);
|
|
169
292
|
}
|
|
170
293
|
break;
|
|
294
|
+
case constant_1.RenameScope.NAME:
|
|
295
|
+
if (newDescriptor.operationId != null) {
|
|
296
|
+
newDescriptor.operationId = applyRenameRule(newDescriptor.operationId, config, apiDescriptor, 0);
|
|
297
|
+
}
|
|
298
|
+
break;
|
|
171
299
|
default:
|
|
172
300
|
// No action needed, keep original descriptor
|
|
173
301
|
break;
|
|
@@ -185,7 +313,7 @@ function rename(config) {
|
|
|
185
313
|
throw new Error('at least one of `style` or `transform` is required');
|
|
186
314
|
}
|
|
187
315
|
if (conf.style === 'kebabCase' && conf.scope === 'refName') {
|
|
188
|
-
throw new Error(`Invalid rename style: ${conf.style}
|
|
316
|
+
throw new Error(`Invalid rename style: ${conf.style}, ${conf.scope}`);
|
|
189
317
|
}
|
|
190
318
|
}
|
|
191
319
|
return {
|
|
@@ -4,23 +4,24 @@ exports.extend = extend;
|
|
|
4
4
|
exports.isMatch = isMatch;
|
|
5
5
|
const prepareConfig_1 = require("../../functions/prepareConfig");
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* @param config
|
|
11
|
-
* @param newConfig
|
|
12
|
-
* @returns
|
|
7
|
+
* Extends the generator configuration:
|
|
8
|
+
* merges the provided newConfig (object or function) with the base config to produce the merged config.
|
|
9
|
+
* When newConfig is not provided, falls back to the original config.
|
|
10
|
+
* @param config base configuration
|
|
11
|
+
* @param newConfig config to merge, or a function that produces the merged config
|
|
12
|
+
* @returns the merged and normalized configuration
|
|
13
13
|
*/
|
|
14
14
|
function extend(config, newConfig) {
|
|
15
|
-
//
|
|
15
|
+
// Compute the extension config based on newConfig's type: call it if it's a function,
|
|
16
|
+
// otherwise use it directly; fall back to the original config if not provided
|
|
16
17
|
const pluginExtendsConfig = typeof newConfig === 'function' ? newConfig(config) : (newConfig ?? config);
|
|
17
|
-
//
|
|
18
|
+
// Use extendsConfig to merge and normalize, ensuring the final structure meets the generator's requirements
|
|
18
19
|
return (0, prepareConfig_1.extendsConfig)(config, pluginExtendsConfig);
|
|
19
20
|
}
|
|
20
21
|
/**
|
|
21
22
|
* Tests if value matches the specified rule
|
|
22
23
|
*/
|
|
23
|
-
function isMatch(value, match) {
|
|
24
|
+
function isMatch(value, match, level = 0) {
|
|
24
25
|
if (!match)
|
|
25
26
|
return true;
|
|
26
27
|
if (typeof match === 'string') {
|
|
@@ -30,7 +31,7 @@ function isMatch(value, match) {
|
|
|
30
31
|
return match.test(value);
|
|
31
32
|
}
|
|
32
33
|
if (typeof match === 'function') {
|
|
33
|
-
return match(value);
|
|
34
|
+
return match(value, level);
|
|
34
35
|
}
|
|
35
36
|
return false;
|
|
36
37
|
}
|
package/dist/template/index.js
CHANGED
|
@@ -4,7 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getPresetTemplatePath = getPresetTemplatePath;
|
|
7
|
-
exports.registerProcessTypeHelper = registerProcessTypeHelper;
|
|
8
7
|
exports.config = config;
|
|
9
8
|
exports.alovaGlobals = alovaGlobals;
|
|
10
9
|
exports.alova = alova;
|
|
@@ -21,27 +20,6 @@ function getPresetTemplatePath(presetName) {
|
|
|
21
20
|
// 编译后在 dist/template/presets 目录
|
|
22
21
|
return node_path_1.default.join(__dirname, 'presets', presetName);
|
|
23
22
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Register processType helper on an hbs instance.
|
|
26
|
-
*
|
|
27
|
-
* Scans the type string for every PascalCase identifier that is in componentNames
|
|
28
|
-
* (and not already prefixed with "ComponentTypes.") and prefixes it.
|
|
29
|
-
* Works uniformly for top-level names, generics, object literals, and arrays.
|
|
30
|
-
*/
|
|
31
|
-
function registerProcessTypeHelper(hbs) {
|
|
32
|
-
hbs.registerHelper('processType', (_typeStr, _componentNames) => {
|
|
33
|
-
const typeStr = _typeStr;
|
|
34
|
-
const componentNames = _componentNames;
|
|
35
|
-
if (!typeStr || !Array.isArray(componentNames) || componentNames.length === 0) {
|
|
36
|
-
return new hbs.SafeString(typeStr || 'unknown');
|
|
37
|
-
}
|
|
38
|
-
const componentSet = new Set(componentNames);
|
|
39
|
-
const result = typeStr.replace(/(?<!ComponentTypes\.)(\b[A-Z]\w*\b)/g, (match) => {
|
|
40
|
-
return componentSet.has(match) ? `ComponentTypes.${match}` : match;
|
|
41
|
-
});
|
|
42
|
-
return new hbs.SafeString(result);
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
23
|
// ========== Template Preset Plugins ==========
|
|
46
24
|
/**
|
|
47
25
|
* worma.config 模板预设 - plugin mode
|
|
@@ -100,9 +78,6 @@ function alova(opts) {
|
|
|
100
78
|
getTemplate() {
|
|
101
79
|
return { path: getPresetTemplatePath(constant_1.PresetTemplateName.ALOVA) };
|
|
102
80
|
},
|
|
103
|
-
onHandlebarsCreated({ hbs }) {
|
|
104
|
-
registerProcessTypeHelper(hbs);
|
|
105
|
-
},
|
|
106
81
|
beforeCodeGenerate({ data }) {
|
|
107
82
|
data.config = {
|
|
108
83
|
...data.config,
|
|
@@ -122,9 +97,6 @@ function axios(opts) {
|
|
|
122
97
|
getTemplate() {
|
|
123
98
|
return { path: getPresetTemplatePath(constant_1.PresetTemplateName.AXIOS) };
|
|
124
99
|
},
|
|
125
|
-
onHandlebarsCreated({ hbs }) {
|
|
126
|
-
registerProcessTypeHelper(hbs);
|
|
127
|
-
},
|
|
128
100
|
beforeCodeGenerate({ data }) {
|
|
129
101
|
data.config = {
|
|
130
102
|
...data.config,
|
|
@@ -144,9 +116,6 @@ function fetch(opts) {
|
|
|
144
116
|
getTemplate() {
|
|
145
117
|
return { path: getPresetTemplatePath(constant_1.PresetTemplateName.FETCH) };
|
|
146
118
|
},
|
|
147
|
-
onHandlebarsCreated({ hbs }) {
|
|
148
|
-
registerProcessTypeHelper(hbs);
|
|
149
|
-
},
|
|
150
119
|
beforeCodeGenerate({ data }) {
|
|
151
120
|
data.config = {
|
|
152
121
|
...data.config,
|
|
@@ -166,9 +135,6 @@ function ky(opts) {
|
|
|
166
135
|
getTemplate() {
|
|
167
136
|
return { path: getPresetTemplatePath(constant_1.PresetTemplateName.KY) };
|
|
168
137
|
},
|
|
169
|
-
onHandlebarsCreated({ hbs }) {
|
|
170
|
-
registerProcessTypeHelper(hbs);
|
|
171
|
-
},
|
|
172
138
|
beforeCodeGenerate({ data }) {
|
|
173
139
|
data.config = {
|
|
174
140
|
...data.config,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{{#or pathParameters queryParameters requestBody}}
|
|
2
2
|
type {{{name}}}ExtraConfig = {
|
|
3
|
-
{{#if pathParameters}}pathParams: {{
|
|
4
|
-
{{/if}}{{#if queryParameters}}params: {{
|
|
5
|
-
{{/if}}{{#if requestBody}}data: {{
|
|
3
|
+
{{#if pathParameters}}pathParams: {{addNamespace pathParameters @root.componentNames}};
|
|
4
|
+
{{/if}}{{#if queryParameters}}params: {{addNamespace queryParameters @root.componentNames}};
|
|
5
|
+
{{/if}}{{#if requestBody}}data: {{addNamespace requestBody @root.componentNames}};
|
|
6
6
|
{{/if}}
|
|
7
7
|
};
|
|
8
8
|
{{/or}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function {{{name}}}<Config extends Alova2MethodConfig<{{
|
|
1
|
+
export declare function {{{name}}}<Config extends Alova2MethodConfig<{{addNamespace response @root.componentNames}}> & {{{name}}}ExtraConfig>(config: Config): Alova2Method<ExtractResponded<Config, '{{{name}}}', {{addNamespace response @root.componentNames}}>>;
|
|
@@ -12,15 +12,15 @@ import type * as ComponentTypes from '../components';
|
|
|
12
12
|
{{#each apis}}
|
|
13
13
|
|
|
14
14
|
interface {{{name}}}ExtraConfig {
|
|
15
|
-
{{#if pathParameters}}pathParams: {{
|
|
16
|
-
{{/if}}{{#if queryParameters}}params: {{
|
|
17
|
-
{{/if}}{{#if requestBody}}data: {{
|
|
15
|
+
{{#if pathParameters}}pathParams: {{addNamespace pathParameters @root.componentNames}};
|
|
16
|
+
{{/if}}{{#if queryParameters}}params: {{addNamespace queryParameters @root.componentNames}};
|
|
17
|
+
{{/if}}{{#if requestBody}}data: {{addNamespace requestBody @root.componentNames}};
|
|
18
18
|
{{/if}}
|
|
19
19
|
}
|
|
20
20
|
{{> api-jsdoc}}
|
|
21
|
-
export function {{{name}}}<Config extends Alova2MethodConfig<{{
|
|
21
|
+
export function {{{name}}}<Config extends Alova2MethodConfig<{{addNamespace response @root.componentNames}}> & {{{name}}}ExtraConfig>(config: Config): Alova2Method<ExtractResponded<Config, '{{{name}}}', {{addNamespace response @root.componentNames}}>> {
|
|
22
22
|
const { url, data, mergedConfig } = buildPayload('{{{path}}}', {{{tag}}}DefaultConfig, {{{name}}}.name, config);
|
|
23
|
-
return alovaInstance.Request<ExtractResponded<Config, '{{{name}}}', {{
|
|
23
|
+
return alovaInstance.Request<ExtractResponded<Config, '{{{name}}}', {{addNamespace response @root.componentNames}}>>({
|
|
24
24
|
...mergedConfig,
|
|
25
25
|
url,
|
|
26
26
|
data,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
type {{{name}}}Response = {{
|
|
1
|
+
type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
2
2
|
type {{{name}}}ExtraConfig = Omit<AxiosRequestConfig, 'data' | 'params'> & {
|
|
3
|
-
{{#if pathParameters}}pathParams: {{
|
|
4
|
-
{{/if}}{{#if queryParameters}}params: {{
|
|
5
|
-
{{/if}}{{#if requestBody}}data: {{
|
|
3
|
+
{{#if pathParameters}}pathParams: {{addNamespace pathParameters @root.componentNames}};
|
|
4
|
+
{{/if}}{{#if queryParameters}}params: {{addNamespace queryParameters @root.componentNames}};
|
|
5
|
+
{{/if}}{{#if requestBody}}data: {{addNamespace requestBody @root.componentNames}};
|
|
6
6
|
{{/if}}
|
|
7
7
|
};
|
|
@@ -9,11 +9,11 @@ import { {{{tagName}}}DefaultConfig } from '.';
|
|
|
9
9
|
|
|
10
10
|
{{#each tagedApis}}
|
|
11
11
|
{{#each apis}}
|
|
12
|
-
type {{{name}}}Response = {{
|
|
12
|
+
type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
13
13
|
type {{{name}}}ExtraConfig = Omit<AxiosRequestConfig, 'data' | 'params'> & {
|
|
14
|
-
{{#if pathParameters}}pathParams: {{
|
|
15
|
-
{{/if}}{{#if queryParameters}}params: {{
|
|
16
|
-
{{/if}}{{#if requestBody}}data: {{
|
|
14
|
+
{{#if pathParameters}}pathParams: {{addNamespace pathParameters @root.componentNames}};
|
|
15
|
+
{{/if}}{{#if queryParameters}}params: {{addNamespace queryParameters @root.componentNames}};
|
|
16
|
+
{{/if}}{{#if requestBody}}data: {{addNamespace requestBody @root.componentNames}};
|
|
17
17
|
{{/if}}
|
|
18
18
|
};
|
|
19
19
|
{{> api-jsdoc}}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const { defineConfig } = require('wormajs');
|
|
2
|
-
const {
|
|
2
|
+
const { swagger, aiDoc{{#if templateImport}}, {{{templateImport}}}{{/if}} } = require('wormajs/plugin');
|
|
3
3
|
|
|
4
4
|
// For more config detailed visit:
|
|
5
5
|
// https://github.com/alovajs/devtools
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineConfig } from 'wormajs';
|
|
2
|
-
import {
|
|
2
|
+
import { swagger, aiDoc{{#if templateImport}}, {{{templateImport}}}{{/if}} } from 'wormajs/plugin';
|
|
3
3
|
|
|
4
4
|
// For more config detailed visit:
|
|
5
5
|
// https://github.com/alovajs/devtools
|
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
generator: [
|
|
2
|
-
{
|
|
3
|
-
/**
|
|
4
|
-
* file input. support:
|
|
5
|
-
* 1. openapi json file url
|
|
6
|
-
* 2. local file
|
|
7
|
-
* 3. string array — each URL will be tried in order, first success wins
|
|
8
|
-
*/
|
|
9
|
-
input: 'http://localhost:3000',
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* output path of interface file and type file.
|
|
13
|
-
* Multiple generators cannot have the same address, otherwise the generated code will overwrite each other.
|
|
14
|
-
*/
|
|
15
|
-
output: 'src/api',
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* platform plugin: auto-resolves OpenAPI file URLs from
|
|
19
|
-
*
|
|
20
|
-
*/
|
|
21
|
-
plugins: [
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* the mediaType of the generated response data. default is `application/json`
|
|
25
|
-
*/
|
|
26
|
-
// responseMediaType: 'application/json',
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* the bodyMediaType of the generated request body data. default is `application/json`
|
|
30
|
-
*/
|
|
31
|
-
// bodyMediaType: 'application/json',
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* type of generated code. The options are `auto/ts/typescript/module/commonjs`
|
|
35
|
-
*/
|
|
36
|
-
// type: 'auto',
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* filter or convert the generated api information, return an apiDescriptor, if this function is not specified, the apiDescriptor object is not converted
|
|
40
|
-
*/
|
|
41
|
-
// handleApi: apiDescriptor => {
|
|
42
|
-
// return apiDescriptor;
|
|
43
|
-
// }
|
|
44
|
-
}
|
|
45
|
-
]
|
|
1
|
+
generator: [
|
|
2
|
+
{
|
|
3
|
+
/**
|
|
4
|
+
* file input. support:
|
|
5
|
+
* 1. openapi json file url
|
|
6
|
+
* 2. local file
|
|
7
|
+
* 3. string array — each URL will be tried in order, first success wins
|
|
8
|
+
*/
|
|
9
|
+
// input: 'http://localhost:3000',
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* output path of interface file and type file.
|
|
13
|
+
* Multiple generators cannot have the same address, otherwise the generated code will overwrite each other.
|
|
14
|
+
*/
|
|
15
|
+
output: 'src/api',
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* swagger platform plugin: auto-resolves OpenAPI file URLs from the base URL.
|
|
19
|
+
* The base URL is passed as the plugin argument (not config.input).
|
|
20
|
+
*/
|
|
21
|
+
plugins: [swagger('http://localhost:3000'), aiDoc({ installSkill: true }), {{{templateCall}}}],
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* the mediaType of the generated response data. default is `application/json`
|
|
25
|
+
*/
|
|
26
|
+
// responseMediaType: 'application/json',
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* the bodyMediaType of the generated request body data. default is `application/json`
|
|
30
|
+
*/
|
|
31
|
+
// bodyMediaType: 'application/json',
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* type of generated code. The options are `auto/ts/typescript/module/commonjs`
|
|
35
|
+
*/
|
|
36
|
+
// type: 'auto',
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* filter or convert the generated api information, return an apiDescriptor, if this function is not specified, the apiDescriptor object is not converted
|
|
40
|
+
*/
|
|
41
|
+
// handleApi: apiDescriptor => {
|
|
42
|
+
// return apiDescriptor;
|
|
43
|
+
// }
|
|
44
|
+
}
|
|
45
|
+
]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineConfig } from 'wormajs';
|
|
2
|
-
import {
|
|
2
|
+
import { swagger, aiDoc{{#if templateImport}}, {{{templateImport}}}{{/if}} } from 'wormajs/plugin';
|
|
3
3
|
|
|
4
4
|
// For more config detailed visit:
|
|
5
5
|
// https://github.com/alovajs/devtools
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
type {{{name}}}Response = {{
|
|
1
|
+
type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
2
2
|
type {{{name}}}ExtraConfig = Omit<RequestInit, 'body'> & {
|
|
3
|
-
{{#if pathParameters}}pathParams: {{
|
|
4
|
-
{{/if}}{{#if queryParameters}}params?: {{
|
|
5
|
-
{{/if}}{{#if requestBody}}body?: {{
|
|
3
|
+
{{#if pathParameters}}pathParams: {{addNamespace pathParameters @root.componentNames}};
|
|
4
|
+
{{/if}}{{#if queryParameters}}params?: {{addNamespace queryParameters @root.componentNames}};
|
|
5
|
+
{{/if}}{{#if requestBody}}body?: {{addNamespace requestBody @root.componentNames}} | BodyInit;
|
|
6
6
|
{{/if}}
|
|
7
7
|
};
|
|
@@ -8,11 +8,11 @@ import { {{{tagName}}}DefaultConfig } from '.';
|
|
|
8
8
|
|
|
9
9
|
{{#each tagedApis}}
|
|
10
10
|
{{#each apis}}
|
|
11
|
-
type {{{name}}}Response = {{
|
|
11
|
+
type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
12
12
|
type {{{name}}}ExtraConfig = Omit<RequestInit, 'body'> & {
|
|
13
|
-
{{#if pathParameters}}pathParams: {{
|
|
14
|
-
{{/if}}{{#if queryParameters}}params?: {{
|
|
15
|
-
{{/if}}{{#if requestBody}}body?: {{
|
|
13
|
+
{{#if pathParameters}}pathParams: {{addNamespace pathParameters @root.componentNames}};
|
|
14
|
+
{{/if}}{{#if queryParameters}}params?: {{addNamespace queryParameters @root.componentNames}};
|
|
15
|
+
{{/if}}{{#if requestBody}}body?: {{addNamespace requestBody @root.componentNames}};
|
|
16
16
|
{{/if}}
|
|
17
17
|
};
|
|
18
18
|
{{> api-jsdoc}}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
type {{{name}}}Response = {{
|
|
1
|
+
type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
2
2
|
{{#or pathParameters queryParameters requestBody}}
|
|
3
3
|
type {{{name}}}ExtraConfig = Options & {
|
|
4
|
-
{{#if pathParameters}}pathParams: {{
|
|
5
|
-
{{/if}}{{#if queryParameters}}searchParams: {{
|
|
6
|
-
{{/if}}{{#if requestBody}}json: {{
|
|
4
|
+
{{#if pathParameters}}pathParams: {{addNamespace pathParameters @root.componentNames}};
|
|
5
|
+
{{/if}}{{#if queryParameters}}searchParams: {{addNamespace queryParameters @root.componentNames}};
|
|
6
|
+
{{/if}}{{#if requestBody}}json: {{addNamespace requestBody @root.componentNames}};
|
|
7
7
|
{{/if}}
|
|
8
8
|
};
|
|
9
9
|
{{/or}}
|
|
@@ -9,11 +9,11 @@ import { {{{tagName}}}DefaultConfig } from '.';
|
|
|
9
9
|
|
|
10
10
|
{{#each tagedApis}}
|
|
11
11
|
{{#each apis}}
|
|
12
|
-
type {{{name}}}Response = {{
|
|
12
|
+
type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
13
13
|
type {{{name}}}ExtraConfig = Options & {
|
|
14
|
-
{{#if pathParameters}}pathParams: {{
|
|
15
|
-
{{/if}}{{#if queryParameters}}searchParams: {{
|
|
16
|
-
{{/if}}{{#if requestBody}}json: {{
|
|
14
|
+
{{#if pathParameters}}pathParams: {{addNamespace pathParameters @root.componentNames}};
|
|
15
|
+
{{/if}}{{#if queryParameters}}searchParams: {{addNamespace queryParameters @root.componentNames}};
|
|
16
|
+
{{/if}}{{#if requestBody}}json: {{addNamespace requestBody @root.componentNames}};
|
|
17
17
|
{{/if}}
|
|
18
18
|
};
|
|
19
19
|
{{> api-jsdoc}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/config.ts","../src/constant.ts","../src/createConfig.ts","../src/defineConfig.ts","../src/generate.ts","../src/index.ts","../src/readConfig.ts","../src/resolveWorkspaces.ts","../src/bin/actions.ts","../src/bin/cli.ts","../src/bin/progressRenderer.ts","../src/bin/renderer.ts","../src/bin/theme.ts","../src/core/WorkerPool.ts","../src/core/loader/index.ts","../src/core/loader/astLoader/helper.ts","../src/core/loader/astLoader/index.ts","../src/core/loader/astLoader/generates/array.ts","../src/core/loader/astLoader/generates/enum.ts","../src/core/loader/astLoader/generates/group.ts","../src/core/loader/astLoader/generates/index.ts","../src/core/loader/astLoader/generates/interface.ts","../src/core/loader/astLoader/generates/simple.ts","../src/core/loader/astLoader/generates/tuple.ts","../src/core/loader/astLoader/generates/type.ts","../src/core/loader/astLoader/generates/utils.ts","../src/core/loader/astLoader/normalize/index.ts","../src/core/loader/astLoader/normalize/normalizer.ts","../src/core/loader/astLoader/normalize/rules/convertTypeArray.ts","../src/core/loader/astLoader/normalize/rules/handleEmptyType.ts","../src/core/loader/astLoader/normalize/rules/inferType.ts","../src/core/loader/astLoader/normalize/rules/mergeAnyOf.ts","../src/core/loader/astLoader/normalize/rules/normalizeCombiningKeywords.ts","../src/core/loader/astLoader/normalize/rules/normalizeEnum.ts","../src/core/loader/astLoader/normalize/rules/normalizeNullType.ts","../src/core/loader/astLoader/normalize/rules/removeRedundantKeywords.ts","../src/core/loader/astLoader/normalize/rules/simplifySingleType.ts","../src/core/loader/astLoader/normalize/rules/validateSchema.ts","../src/core/loader/astLoader/parsers/array.ts","../src/core/loader/astLoader/parsers/const.ts","../src/core/loader/astLoader/parsers/enum.ts","../src/core/loader/astLoader/parsers/group.ts","../src/core/loader/astLoader/parsers/index.ts","../src/core/loader/astLoader/parsers/object.ts","../src/core/loader/astLoader/parsers/reference.ts","../src/core/loader/astLoader/parsers/simple.ts","../src/core/loader/astLoader/parsers/tuple.ts","../src/core/loader/astLoader/parsers/type.ts","../src/core/loader/astLoader/parsers/utils.ts","../src/core/loader/astLoader/parsers/forward/array.ts","../src/core/loader/astLoader/parsers/forward/const.ts","../src/core/loader/astLoader/parsers/forward/enum.ts","../src/core/loader/astLoader/parsers/forward/group.ts","../src/core/loader/astLoader/parsers/forward/index.ts","../src/core/loader/astLoader/parsers/forward/object.ts","../src/core/loader/astLoader/parsers/forward/tuple.ts","../src/core/loader/astLoader/parsers/forward/type.ts","../src/core/loader/callingCodeLoader/helper.ts","../src/core/loader/callingCodeLoader/index.ts","../src/core/loader/schemaLoader/index.ts","../src/core/loader/standardLoader/helper.ts","../src/core/loader/standardLoader/index.ts","../src/core/loader/standardLoader/standards.ts","../src/core/parser/index.ts","../src/core/parser/openApiParser/helper.ts","../src/core/parser/openApiParser/index.ts","../src/core/parser/templateParser/helper.ts","../src/core/parser/templateParser/index.ts","../src/core/workerPool/index.ts","../src/core/workerPool/poolManager.ts","../src/core/workerPool/swagger2Worker.ts","../src/core/workerPool/worker.ts","../src/functions/getAutoTemplateType.ts","../src/functions/getFrameworkTag.ts","../src/functions/prepareConfig.ts","../src/functions/readWormaRc.ts","../src/functions/wormaJson.ts","../src/helper/PluginDriver.ts","../src/helper/comment.ts","../src/helper/index.ts","../src/helper/progress.ts","../src/helper/config/ConfigHelper.ts","../src/helper/config/ConfigManager.ts","../src/helper/config/GeneratorHelper.ts","../src/helper/config/index.ts","../src/helper/config/type.ts","../src/helper/config/zType.ts","../src/helper/document/index.ts","../src/helper/logger/index.ts","../src/helper/template/index.ts","../src/plugins/createPlugin.ts","../src/plugins/index.ts","../src/plugins/presets/aiDoc.ts","../src/plugins/presets/apifox.ts","../src/plugins/presets/filterApi.ts","../src/plugins/presets/importType.ts","../src/plugins/presets/
|
|
1
|
+
{"root":["../src/config.ts","../src/constant.ts","../src/createConfig.ts","../src/defineConfig.ts","../src/generate.ts","../src/index.ts","../src/readConfig.ts","../src/resolveWorkspaces.ts","../src/bin/actions.ts","../src/bin/cli.ts","../src/bin/progressRenderer.ts","../src/bin/renderer.ts","../src/bin/theme.ts","../src/core/WorkerPool.ts","../src/core/loader/index.ts","../src/core/loader/astLoader/helper.ts","../src/core/loader/astLoader/index.ts","../src/core/loader/astLoader/generates/array.ts","../src/core/loader/astLoader/generates/enum.ts","../src/core/loader/astLoader/generates/group.ts","../src/core/loader/astLoader/generates/index.ts","../src/core/loader/astLoader/generates/interface.ts","../src/core/loader/astLoader/generates/simple.ts","../src/core/loader/astLoader/generates/tuple.ts","../src/core/loader/astLoader/generates/type.ts","../src/core/loader/astLoader/generates/utils.ts","../src/core/loader/astLoader/normalize/index.ts","../src/core/loader/astLoader/normalize/normalizer.ts","../src/core/loader/astLoader/normalize/rules/convertTypeArray.ts","../src/core/loader/astLoader/normalize/rules/handleEmptyType.ts","../src/core/loader/astLoader/normalize/rules/inferType.ts","../src/core/loader/astLoader/normalize/rules/mergeAnyOf.ts","../src/core/loader/astLoader/normalize/rules/normalizeCombiningKeywords.ts","../src/core/loader/astLoader/normalize/rules/normalizeEnum.ts","../src/core/loader/astLoader/normalize/rules/normalizeNullType.ts","../src/core/loader/astLoader/normalize/rules/removeRedundantKeywords.ts","../src/core/loader/astLoader/normalize/rules/simplifySingleType.ts","../src/core/loader/astLoader/normalize/rules/validateSchema.ts","../src/core/loader/astLoader/parsers/array.ts","../src/core/loader/astLoader/parsers/const.ts","../src/core/loader/astLoader/parsers/enum.ts","../src/core/loader/astLoader/parsers/group.ts","../src/core/loader/astLoader/parsers/index.ts","../src/core/loader/astLoader/parsers/object.ts","../src/core/loader/astLoader/parsers/reference.ts","../src/core/loader/astLoader/parsers/simple.ts","../src/core/loader/astLoader/parsers/tuple.ts","../src/core/loader/astLoader/parsers/type.ts","../src/core/loader/astLoader/parsers/utils.ts","../src/core/loader/astLoader/parsers/forward/array.ts","../src/core/loader/astLoader/parsers/forward/const.ts","../src/core/loader/astLoader/parsers/forward/enum.ts","../src/core/loader/astLoader/parsers/forward/group.ts","../src/core/loader/astLoader/parsers/forward/index.ts","../src/core/loader/astLoader/parsers/forward/object.ts","../src/core/loader/astLoader/parsers/forward/tuple.ts","../src/core/loader/astLoader/parsers/forward/type.ts","../src/core/loader/callingCodeLoader/helper.ts","../src/core/loader/callingCodeLoader/index.ts","../src/core/loader/schemaLoader/index.ts","../src/core/loader/standardLoader/helper.ts","../src/core/loader/standardLoader/index.ts","../src/core/loader/standardLoader/standards.ts","../src/core/parser/index.ts","../src/core/parser/openApiParser/helper.ts","../src/core/parser/openApiParser/index.ts","../src/core/parser/templateParser/helper.ts","../src/core/parser/templateParser/index.ts","../src/core/workerPool/index.ts","../src/core/workerPool/poolManager.ts","../src/core/workerPool/swagger2Worker.ts","../src/core/workerPool/worker.ts","../src/functions/getAutoTemplateType.ts","../src/functions/getFrameworkTag.ts","../src/functions/prepareConfig.ts","../src/functions/readWormaRc.ts","../src/functions/wormaJson.ts","../src/helper/PluginDriver.ts","../src/helper/comment.ts","../src/helper/index.ts","../src/helper/progress.ts","../src/helper/config/ConfigHelper.ts","../src/helper/config/ConfigManager.ts","../src/helper/config/GeneratorHelper.ts","../src/helper/config/index.ts","../src/helper/config/type.ts","../src/helper/config/zType.ts","../src/helper/document/index.ts","../src/helper/logger/index.ts","../src/helper/template/index.ts","../src/plugins/createPlugin.ts","../src/plugins/index.ts","../src/plugins/presets/aiDoc.ts","../src/plugins/presets/apifox.ts","../src/plugins/presets/filterApi.ts","../src/plugins/presets/importType.ts","../src/plugins/presets/rename.ts","../src/plugins/presets/tagModifier.ts","../src/plugins/presets/utils.ts","../src/plugins/presets/payloadModifier/hepler.ts","../src/plugins/presets/payloadModifier/index.ts","../src/plugins/presets/payloadModifier/type.ts","../src/plugins/presets/platform/fastapi.ts","../src/plugins/presets/platform/index.ts","../src/plugins/presets/platform/knife4j.ts","../src/plugins/presets/platform/shared.ts","../src/plugins/presets/platform/swagger.ts","../src/plugins/presets/platform/yapi.ts","../src/template/index.ts","../src/type/api.ts","../src/type/ast.ts","../src/type/base.ts","../src/type/index.ts","../src/type/lib.ts","../src/type/openapi.ts","../src/utils/base.ts","../src/utils/format.ts","../src/utils/index.ts","../src/utils/openapi.ts","../src/utils/readPackageJson.ts","../src/utils/template.ts"],"version":"5.9.3"}
|
package/dist/utils/template.js
CHANGED
|
@@ -76,6 +76,29 @@ function registerCommonHelpers(hbs) {
|
|
|
76
76
|
return text;
|
|
77
77
|
return text.split('\n').map(line => line.replace(/^\* ?/, '')).join('\n');
|
|
78
78
|
});
|
|
79
|
+
/**
|
|
80
|
+
* Scan the type string for every PascalCase identifier that is in componentNames
|
|
81
|
+
* (and not already prefixed with `${importName}.`) and prefix it.
|
|
82
|
+
* Works uniformly for top-level names, generics, object literals, and arrays.
|
|
83
|
+
*
|
|
84
|
+
* @param typeStr The type expression to process.
|
|
85
|
+
* @param componentNames The list of component schema names to prefix.
|
|
86
|
+
* @param importName The imported namespace name to prefix with. Defaults to "ComponentTypes".
|
|
87
|
+
*/
|
|
88
|
+
hbs.registerHelper('addNamespace', (typeStr, componentNames, importName) => {
|
|
89
|
+
const type = typeStr;
|
|
90
|
+
const names = componentNames;
|
|
91
|
+
const importPrefix = (typeof importName === 'string' && importName.length > 0) ? importName : 'ComponentTypes';
|
|
92
|
+
if (!type || !Array.isArray(names) || names.length === 0) {
|
|
93
|
+
return new hbs.SafeString(type || 'unknown');
|
|
94
|
+
}
|
|
95
|
+
const nameSet = new Set(names);
|
|
96
|
+
const escapedPrefix = importPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
97
|
+
const result = type.replace(new RegExp(`(?<!${escapedPrefix}\\.)(\\b[A-Z]\\w*\\b)`, 'g'), (match) => {
|
|
98
|
+
return nameSet.has(match) ? `${importPrefix}.${match}` : match;
|
|
99
|
+
});
|
|
100
|
+
return new hbs.SafeString(result);
|
|
101
|
+
});
|
|
79
102
|
}
|
|
80
103
|
/**
|
|
81
104
|
* Pass in text content and generate a custom file in the specified directory
|
package/package.json
CHANGED
package/typings/plugins.d.ts
CHANGED
|
@@ -597,33 +597,106 @@ export interface ModifierConfig<T extends Schema> {
|
|
|
597
597
|
export type PayloadModifierConfig = ModifierConfig<Schema>;
|
|
598
598
|
export declare function payloadModifier(configs: PayloadModifierConfig[]): ApiPlugin;
|
|
599
599
|
/**
|
|
600
|
-
*
|
|
600
|
+
* FastAPI platform plugin.
|
|
601
|
+
*
|
|
602
|
+
* Pass the base URL of your FastAPI app; the plugin will try `/openapi.json`
|
|
603
|
+
* first, then fall back to the bare base URL.
|
|
604
|
+
*
|
|
605
|
+
* @param input - base URL string, or an array of base URLs
|
|
606
|
+
*
|
|
607
|
+
* @example
|
|
608
|
+
* ```ts
|
|
609
|
+
* plugins: [fastapi('http://fastapi-example.dokkuapp.com'), alovaGlobals()]
|
|
610
|
+
* ```
|
|
601
611
|
*/
|
|
602
|
-
export
|
|
612
|
+
export declare const fastapi: (input: string | string[]) => ApiPlugin;
|
|
603
613
|
/**
|
|
604
|
-
*
|
|
614
|
+
* Knife4j platform plugin.
|
|
605
615
|
*
|
|
606
|
-
* Pass
|
|
607
|
-
*
|
|
608
|
-
*
|
|
616
|
+
* Pass the base URL of your Knife4j instance; the plugin will try the OAS3
|
|
617
|
+
* endpoint (springdoc) first, then the Swagger2 endpoint (springfox), then the
|
|
618
|
+
* bare base URL.
|
|
609
619
|
*
|
|
610
|
-
* @param
|
|
611
|
-
* @returns ApiPlugin
|
|
620
|
+
* @param input - base URL string, or an array of base URLs
|
|
612
621
|
*
|
|
613
622
|
* @example
|
|
614
623
|
* ```ts
|
|
615
|
-
*
|
|
624
|
+
* plugins: [knife4j('https://openapi3.demo.knife4jnext.com'), alovaGlobals()]
|
|
625
|
+
* ```
|
|
626
|
+
*/
|
|
627
|
+
export declare const knife4j: (input: string | string[]) => ApiPlugin;
|
|
628
|
+
/**
|
|
629
|
+
* Swagger platform plugin.
|
|
630
|
+
*
|
|
631
|
+
* Pass the base URL of your Swagger UI / server; the plugin will try several
|
|
632
|
+
* common OpenAPI document endpoints (OAS3 first, then Swagger2, then the bare
|
|
633
|
+
* base URL) and let the framework pick the first one that responds.
|
|
634
|
+
*
|
|
635
|
+
* @param input - base URL string, or an array of base URLs
|
|
636
|
+
*
|
|
637
|
+
* @example
|
|
638
|
+
* ```ts
|
|
639
|
+
* import { swagger, alovaGlobals } from 'wormajs/plugin';
|
|
616
640
|
*
|
|
617
641
|
* defineConfig({
|
|
618
642
|
* generator: [{
|
|
619
|
-
*
|
|
620
|
-
* plugins: [platform('swagger'), alovaGlobals()],
|
|
643
|
+
* plugins: [swagger('https://petstore3.swagger.io'), alovaGlobals()],
|
|
621
644
|
* output: './src/api',
|
|
622
645
|
* }]
|
|
623
646
|
* });
|
|
624
647
|
* ```
|
|
625
648
|
*/
|
|
626
|
-
export declare
|
|
649
|
+
export declare const swagger: (input: string | string[]) => ApiPlugin;
|
|
650
|
+
export interface YapiOptions {
|
|
651
|
+
/** YApi 服务基础地址,例如 `https://yapi.xxx.com` */
|
|
652
|
+
url: string;
|
|
653
|
+
/** 项目 ID,必填,用于拼装导出地址 */
|
|
654
|
+
pid: string | number;
|
|
655
|
+
/** OpenAPI 类型,默认 `OpenAPIV2` */
|
|
656
|
+
type?: string;
|
|
657
|
+
/** 接口状态,默认 `all` */
|
|
658
|
+
status?: string;
|
|
659
|
+
/** 是否包含 wiki,默认 `true` */
|
|
660
|
+
isWiki?: boolean;
|
|
661
|
+
/** 登录 cookie。也可通过 fetchOptions.headers.cookie 传入 */
|
|
662
|
+
cookie?: string;
|
|
663
|
+
/** 额外的 fetch 超时(毫秒) */
|
|
664
|
+
timeout?: number;
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* YApi platform plugin.
|
|
668
|
+
*
|
|
669
|
+
* YApi projects are private, so the OpenAPI document must be exported through
|
|
670
|
+
* YApi's own export endpoint, authenticated with your login cookie. The plugin
|
|
671
|
+
* builds the export URL from the server base URL (`url`) plus the required
|
|
672
|
+
* `pid` and the optional `type` / `status` / `isWiki` query params (which
|
|
673
|
+
* default to `OpenAPIV2`, `all`, and `true` respectively).
|
|
674
|
+
*
|
|
675
|
+
* `url`, `pid` and `cookie` are required — the plugin throws a clear error when
|
|
676
|
+
* any is missing.
|
|
677
|
+
*
|
|
678
|
+
* @param options - `{ url, pid, cookie?, type?, status?, isWiki?, timeout? }`
|
|
679
|
+
*
|
|
680
|
+
* @example
|
|
681
|
+
* ```ts
|
|
682
|
+
* import { yapi, alovaGlobals } from 'wormajs/plugin';
|
|
683
|
+
*
|
|
684
|
+
* defineConfig({
|
|
685
|
+
* generator: [{
|
|
686
|
+
* plugins: [
|
|
687
|
+
* yapi({
|
|
688
|
+
* url: 'https://yapi.xxx.com',
|
|
689
|
+
* pid: 123,
|
|
690
|
+
* cookie: '_yapi_token=xxx; _yapi_uid=yyy',
|
|
691
|
+
* }),
|
|
692
|
+
* alovaGlobals(),
|
|
693
|
+
* ],
|
|
694
|
+
* output: './src/api',
|
|
695
|
+
* }]
|
|
696
|
+
* });
|
|
697
|
+
* ```
|
|
698
|
+
*/
|
|
699
|
+
export declare function yapi(options: YapiOptions): ApiPlugin;
|
|
627
700
|
/**
|
|
628
701
|
* Rename style options
|
|
629
702
|
*/
|
|
@@ -635,7 +708,7 @@ export interface RenameConfig {
|
|
|
635
708
|
/**
|
|
636
709
|
* Target scope for renaming, defaults to 'url'
|
|
637
710
|
*/
|
|
638
|
-
scope?: "url" | "params" | "pathParams" | "data" | "response" | "refName";
|
|
711
|
+
scope?: "url" | "params" | "pathParams" | "data" | "response" | "refName" | "name";
|
|
639
712
|
/**
|
|
640
713
|
* Matching rule for selective renaming:
|
|
641
714
|
* - string: target contains this string
|
|
@@ -643,7 +716,7 @@ export interface RenameConfig {
|
|
|
643
716
|
* - function: custom matching logic
|
|
644
717
|
* If not specified, all targets will be processed
|
|
645
718
|
*/
|
|
646
|
-
match?: string | RegExp | ((key: string) => boolean);
|
|
719
|
+
match?: string | RegExp | ((key: string, level?: number) => boolean);
|
|
647
720
|
/**
|
|
648
721
|
* Naming style to apply
|
|
649
722
|
*/
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.platform = platform;
|
|
4
|
-
const constant_1 = require("../../constant");
|
|
5
|
-
/**
|
|
6
|
-
* Generate OpenAPI file URLs based on platform type.
|
|
7
|
-
* For Swagger and Knife4j, generates multiple URLs covering both OAS3 and Swagger2 endpoints.
|
|
8
|
-
*/
|
|
9
|
-
function resolvePlatformUrls(baseUrl, platformType) {
|
|
10
|
-
// Normalize: remove trailing slash
|
|
11
|
-
const base = baseUrl.replace(/\/+$/, '');
|
|
12
|
-
switch (platformType) {
|
|
13
|
-
case 'swagger':
|
|
14
|
-
// Try OAS3 first, then Swagger2, then generic openapi.json
|
|
15
|
-
return [
|
|
16
|
-
`${base}/openapi.json`,
|
|
17
|
-
`${base}/v2/swagger.json`,
|
|
18
|
-
`${base}/api/v3/openapi.json`,
|
|
19
|
-
baseUrl,
|
|
20
|
-
];
|
|
21
|
-
case 'knife4j':
|
|
22
|
-
// Try OAS3 first (springdoc), then Swagger2 (springfox)
|
|
23
|
-
return [
|
|
24
|
-
`${base}/v3/api-docs`,
|
|
25
|
-
`${base}/v2/api-docs`,
|
|
26
|
-
baseUrl,
|
|
27
|
-
];
|
|
28
|
-
case 'fastapi':
|
|
29
|
-
return [`${base}/openapi.json`, baseUrl];
|
|
30
|
-
case 'yapi':
|
|
31
|
-
// YApi requires pid and token in URL, use input as-is
|
|
32
|
-
return [baseUrl];
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Platform plugin for auto-resolving OpenAPI file URLs.
|
|
37
|
-
*
|
|
38
|
-
* Pass a platform type (e.g., `'swagger'`) and the plugin will use `config.input`
|
|
39
|
-
* as the base URL to generate candidate OpenAPI file URLs. The framework will try
|
|
40
|
-
* each URL in order and use the first successful response.
|
|
41
|
-
*
|
|
42
|
-
* @param platformType - The platform type: 'swagger' | 'knife4j' | 'fastapi' | 'yapi'
|
|
43
|
-
* @returns ApiPlugin
|
|
44
|
-
*
|
|
45
|
-
* @example
|
|
46
|
-
* ```ts
|
|
47
|
-
* import { platform, alovaGlobals } from 'wormajs/plugin';
|
|
48
|
-
*
|
|
49
|
-
* defineConfig({
|
|
50
|
-
* generator: [{
|
|
51
|
-
* input: 'https://petstore3.swagger.io',
|
|
52
|
-
* plugins: [platform('swagger'), alovaGlobals()],
|
|
53
|
-
* output: './src/api',
|
|
54
|
-
* }]
|
|
55
|
-
* });
|
|
56
|
-
* ```
|
|
57
|
-
*/
|
|
58
|
-
function platform(platformType) {
|
|
59
|
-
return {
|
|
60
|
-
name: constant_1.PluginName.PLATFORM,
|
|
61
|
-
config({ config }) {
|
|
62
|
-
const raw = config.input;
|
|
63
|
-
if (!raw)
|
|
64
|
-
return config;
|
|
65
|
-
// Normalize to an array of base URLs, deduplicate
|
|
66
|
-
const inputs = Array.isArray(raw) ? [...new Set(raw)] : [raw];
|
|
67
|
-
// For each input, generate platform URLs, then flatten
|
|
68
|
-
config.input = inputs.flatMap(url => resolvePlatformUrls(url, platformType));
|
|
69
|
-
return config;
|
|
70
|
-
},
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
exports.default = platform;
|