wormajs 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/constant.js +20 -20
- package/dist/core/loader/astLoader/generates/tuple.js +1 -1
- package/dist/core/loader/astLoader/normalize/index.js +1 -1
- package/dist/core/loader/astLoader/normalize/normalizer.js +8 -8
- package/dist/core/loader/astLoader/normalize/rules/mergeAnyOf.js +9 -8
- package/dist/core/loader/astLoader/normalize/rules/normalizeCombiningKeywords.js +6 -6
- package/dist/core/loader/astLoader/normalize/rules/normalizeNullType.js +1 -1
- package/dist/core/loader/astLoader/parsers/const.js +4 -4
- package/dist/core/loader/astLoader/parsers/enum.js +3 -3
- package/dist/core/loader/astLoader/parsers/forward/array.js +3 -3
- package/dist/core/loader/astLoader/parsers/forward/const.js +3 -3
- package/dist/core/loader/astLoader/parsers/forward/enum.js +2 -2
- package/dist/core/loader/astLoader/parsers/forward/group.js +4 -4
- package/dist/core/loader/astLoader/parsers/forward/object.js +4 -4
- package/dist/core/loader/astLoader/parsers/forward/tuple.js +3 -3
- package/dist/core/loader/astLoader/parsers/group.js +1 -1
- package/dist/core/loader/astLoader/parsers/tuple.js +2 -2
- package/dist/core/loader/standardLoader/helper.js +1 -1
- package/dist/core/parser/templateParser/helper.js +5 -5
- package/dist/core/parser/templateParser/index.js +9 -7
- package/dist/functions/wormaJson.js +2 -2
- package/dist/helper/config/ConfigManager.js +10 -10
- package/dist/helper/config/zType.js +1 -1
- package/dist/helper/document/index.js +11 -11
- package/dist/helper/logger/index.js +1 -1
- package/dist/helper/template/index.js +9 -9
- package/dist/plugins/presets/aiDoc.js +1 -1
- package/dist/plugins/presets/apifox.js +2 -2
- package/dist/plugins/presets/payloadModifier/index.js +3 -0
- package/dist/plugins/presets/rename.js +5 -0
- package/dist/readConfig.js +9 -9
- package/dist/template/index.js +14 -14
- package/dist/template/presets/ai-doc/SKILL.md.handlebars +3 -3
- package/dist/template/presets/alova/common/helper.cjs.handlebars +18 -3
- package/dist/template/presets/alova/common/services/#index.cjs.handlebars +2 -2
- package/dist/template/presets/alova/common/services/{tag}.cjs.handlebars +7 -9
- package/dist/template/presets/alova/common/services/{tag}.d.cts.handlebars +5 -7
- package/dist/template/presets/alova/module/helper.js.handlebars +17 -2
- package/dist/template/presets/alova/module/services/#index.js.handlebars +1 -1
- package/dist/template/presets/alova/module/services/{tag}.d.ts.handlebars +5 -7
- package/dist/template/presets/alova/module/services/{tag}.js.handlebars +6 -6
- package/dist/template/presets/alova/partials/comment.handlebars +11 -2
- package/dist/template/presets/alova/partials/extract-responded.handlebars +3 -3
- package/dist/template/presets/alova/partials/typed-body.handlebars +3 -1
- package/dist/template/presets/alova/typescript/helper.ts.handlebars +11 -6
- package/dist/template/presets/alova/typescript/services/#index.ts.handlebars +1 -1
- package/dist/template/presets/alova/typescript/services/{tag}.ts.handlebars +6 -8
- package/dist/template/presets/alova-globals/partials/comment.handlebars +11 -2
- package/dist/template/presets/alova-globals/partials/globals-d-ts.handlebars +1 -1
- package/dist/template/presets/axios/common/helper.cjs.handlebars +18 -3
- package/dist/template/presets/axios/common/services/#index.cjs.handlebars +2 -2
- package/dist/template/presets/axios/common/services/{tag}.cjs.handlebars +25 -28
- package/dist/template/presets/axios/common/services/{tag}.d.cts.handlebars +1 -3
- package/dist/template/presets/axios/module/helper.js.handlebars +17 -2
- package/dist/template/presets/axios/module/services/#index.js.handlebars +2 -2
- package/dist/template/presets/axios/module/services/{tag}.d.ts.handlebars +1 -3
- package/dist/template/presets/axios/module/services/{tag}.js.handlebars +20 -20
- package/dist/template/presets/axios/partials/comment.handlebars +11 -2
- package/dist/template/presets/axios/typescript/helper.ts.handlebars +11 -6
- package/dist/template/presets/axios/typescript/services/#index.ts.handlebars +1 -1
- package/dist/template/presets/axios/typescript/services/{tag}.ts.handlebars +6 -8
- package/dist/template/presets/fetch/common/helper.cjs.handlebars +18 -3
- package/dist/template/presets/fetch/common/services/#index.cjs.handlebars +2 -2
- package/dist/template/presets/fetch/common/services/{tag}.cjs.handlebars +6 -9
- package/dist/template/presets/fetch/common/services/{tag}.d.cts.handlebars +1 -3
- package/dist/template/presets/fetch/module/helper.js.handlebars +17 -2
- package/dist/template/presets/fetch/module/services/#index.js.handlebars +2 -2
- package/dist/template/presets/fetch/module/services/{tag}.d.ts.handlebars +1 -3
- package/dist/template/presets/fetch/module/services/{tag}.js.handlebars +6 -6
- package/dist/template/presets/fetch/partials/comment.handlebars +11 -2
- package/dist/template/presets/fetch/typescript/helper.ts.handlebars +11 -6
- package/dist/template/presets/fetch/typescript/services/#index.ts.handlebars +1 -1
- package/dist/template/presets/fetch/typescript/services/{tag}.ts.handlebars +6 -8
- package/dist/template/presets/ky/module/helper.js.handlebars +17 -2
- package/dist/template/presets/ky/module/services/#index.js.handlebars +2 -2
- package/dist/template/presets/ky/module/services/{tag}.d.ts.handlebars +1 -3
- package/dist/template/presets/ky/module/services/{tag}.js.handlebars +6 -6
- package/dist/template/presets/ky/partials/comment.handlebars +11 -2
- package/dist/template/presets/ky/typescript/helper.ts.handlebars +11 -6
- package/dist/template/presets/ky/typescript/services/#index.ts.handlebars +1 -1
- package/dist/template/presets/ky/typescript/services/{tag}.ts.handlebars +6 -8
- package/dist/utils/base.js +9 -9
- package/dist/utils/openapi.js +9 -9
- package/package.json +1 -1
- package/typings/index.d.ts +1 -1
- package/typings/plugins.d.ts +30 -19
package/README.md
CHANGED
|
@@ -85,8 +85,8 @@ Effective contributions will win you a certain reputation in the worma community
|
|
|
85
85
|
|
|
86
86
|
## Contributors
|
|
87
87
|
|
|
88
|
-
<a href="https://github.com/alovajs/
|
|
89
|
-
<img src="https://contrib.rocks/image?repo=alovajs/
|
|
88
|
+
<a href="https://github.com/alovajs/devtools/graphs/contributors">
|
|
89
|
+
<img src="https://contrib.rocks/image?repo=alovajs/devtools&max=30&columns=10" />
|
|
90
90
|
</a>
|
|
91
91
|
|
|
92
92
|
## LICENSE
|
package/dist/constant.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// ============================================================
|
|
3
|
-
//
|
|
3
|
+
// Enumeration constant definitions — centrally manage all hardcoded string/number constants in the project
|
|
4
4
|
// ============================================================
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.FRAMEWORK_NAMES = exports.MODULE_TYPE_TO_KIND = exports.MODULE_TYPE_DIRS = exports.ModuleTypeDir = exports.PresetTemplateName = exports.TemplateSkipDir = exports.TemplatePlaceholder = exports.PluginName = exports.FilterScope = exports.RenameScope = exports.ParameterIn = exports.TEMPLATE_EXTENSIONS = exports.FileExtension = exports.FrameworkName = exports.ModuleKind = exports.PlatformTypeEnum = exports.ConfigTypeEnum = exports.TemplateTypeEnum = void 0;
|
|
7
7
|
exports.getTypeFileExtension = getTypeFileExtension;
|
|
8
|
-
/**
|
|
8
|
+
/** Template code generation type */
|
|
9
9
|
var TemplateTypeEnum;
|
|
10
10
|
(function (TemplateTypeEnum) {
|
|
11
11
|
TemplateTypeEnum["TYPESCRIPT"] = "typescript";
|
|
12
12
|
TemplateTypeEnum["MODULE"] = "module";
|
|
13
13
|
TemplateTypeEnum["COMMONJS"] = "commonjs";
|
|
14
14
|
})(TemplateTypeEnum || (exports.TemplateTypeEnum = TemplateTypeEnum = {}));
|
|
15
|
-
/**
|
|
15
|
+
/** The type field value in config (adds auto/ts options over TemplateTypeEnum) */
|
|
16
16
|
var ConfigTypeEnum;
|
|
17
17
|
(function (ConfigTypeEnum) {
|
|
18
18
|
ConfigTypeEnum["AUTO"] = "auto";
|
|
@@ -21,7 +21,7 @@ var ConfigTypeEnum;
|
|
|
21
21
|
ConfigTypeEnum["MODULE"] = "module";
|
|
22
22
|
ConfigTypeEnum["COMMONJS"] = "commonjs";
|
|
23
23
|
})(ConfigTypeEnum || (exports.ConfigTypeEnum = ConfigTypeEnum = {}));
|
|
24
|
-
/**
|
|
24
|
+
/** Supported OpenAPI platforms */
|
|
25
25
|
var PlatformTypeEnum;
|
|
26
26
|
(function (PlatformTypeEnum) {
|
|
27
27
|
PlatformTypeEnum["SWAGGER"] = "swagger";
|
|
@@ -29,13 +29,13 @@ var PlatformTypeEnum;
|
|
|
29
29
|
PlatformTypeEnum["FASTAPI"] = "fastapi";
|
|
30
30
|
PlatformTypeEnum["YAPI"] = "yapi";
|
|
31
31
|
})(PlatformTypeEnum || (exports.PlatformTypeEnum = PlatformTypeEnum = {}));
|
|
32
|
-
/**
|
|
32
|
+
/** Module system type */
|
|
33
33
|
var ModuleKind;
|
|
34
34
|
(function (ModuleKind) {
|
|
35
35
|
ModuleKind["ES_MODULE"] = "ESModule";
|
|
36
36
|
ModuleKind["COMMON_JS"] = "commonJs";
|
|
37
37
|
})(ModuleKind || (exports.ModuleKind = ModuleKind = {}));
|
|
38
|
-
/**
|
|
38
|
+
/** Frontend framework names */
|
|
39
39
|
var FrameworkName;
|
|
40
40
|
(function (FrameworkName) {
|
|
41
41
|
FrameworkName["VUE"] = "vue";
|
|
@@ -44,7 +44,7 @@ var FrameworkName;
|
|
|
44
44
|
FrameworkName["SOLID_JS"] = "solid-js";
|
|
45
45
|
FrameworkName["NUXT"] = "nuxt";
|
|
46
46
|
})(FrameworkName || (exports.FrameworkName = FrameworkName = {}));
|
|
47
|
-
/**
|
|
47
|
+
/** Template file extensions */
|
|
48
48
|
var FileExtension;
|
|
49
49
|
(function (FileExtension) {
|
|
50
50
|
FileExtension["HBS"] = ".hbs";
|
|
@@ -59,9 +59,9 @@ var FileExtension;
|
|
|
59
59
|
FileExtension["D_CTS"] = ".d.cts";
|
|
60
60
|
FileExtension["D_MTS"] = ".d.mts";
|
|
61
61
|
})(FileExtension || (exports.FileExtension = FileExtension = {}));
|
|
62
|
-
/** Handlebars
|
|
62
|
+
/** List of Handlebars template file extensions (excluding plain ts/js extensions) */
|
|
63
63
|
exports.TEMPLATE_EXTENSIONS = Object.values(FileExtension);
|
|
64
|
-
/** OpenAPI
|
|
64
|
+
/** OpenAPI parameter locations */
|
|
65
65
|
var ParameterIn;
|
|
66
66
|
(function (ParameterIn) {
|
|
67
67
|
ParameterIn["QUERY"] = "query";
|
|
@@ -69,7 +69,7 @@ var ParameterIn;
|
|
|
69
69
|
ParameterIn["HEADER"] = "header";
|
|
70
70
|
ParameterIn["COOKIE"] = "cookie";
|
|
71
71
|
})(ParameterIn || (exports.ParameterIn = ParameterIn = {}));
|
|
72
|
-
/**
|
|
72
|
+
/** Rename scope types */
|
|
73
73
|
var RenameScope;
|
|
74
74
|
(function (RenameScope) {
|
|
75
75
|
RenameScope["URL"] = "url";
|
|
@@ -80,13 +80,13 @@ var RenameScope;
|
|
|
80
80
|
RenameScope["REF_NAME"] = "refName";
|
|
81
81
|
RenameScope["NAME"] = "name";
|
|
82
82
|
})(RenameScope || (exports.RenameScope = RenameScope = {}));
|
|
83
|
-
/**
|
|
83
|
+
/** Filter scope types */
|
|
84
84
|
var FilterScope;
|
|
85
85
|
(function (FilterScope) {
|
|
86
86
|
FilterScope["URL"] = "url";
|
|
87
87
|
FilterScope["TAG"] = "tag";
|
|
88
88
|
})(FilterScope || (exports.FilterScope = FilterScope = {}));
|
|
89
|
-
/**
|
|
89
|
+
/** Built-in plugin names */
|
|
90
90
|
var PluginName;
|
|
91
91
|
(function (PluginName) {
|
|
92
92
|
PluginName["TAG_MODIFIER"] = "tagModifier";
|
|
@@ -107,19 +107,19 @@ var PluginName;
|
|
|
107
107
|
PluginName["TEMPLATE_KY"] = "templateKy";
|
|
108
108
|
PluginName["TEMPLATE_CONFIG"] = "templateConfig";
|
|
109
109
|
})(PluginName || (exports.PluginName = PluginName = {}));
|
|
110
|
-
/**
|
|
110
|
+
/** Template placeholders */
|
|
111
111
|
var TemplatePlaceholder;
|
|
112
112
|
(function (TemplatePlaceholder) {
|
|
113
113
|
TemplatePlaceholder["TAG"] = "{tag}";
|
|
114
114
|
TemplatePlaceholder["API"] = "{api}";
|
|
115
115
|
})(TemplatePlaceholder || (exports.TemplatePlaceholder = TemplatePlaceholder = {}));
|
|
116
|
-
/**
|
|
116
|
+
/** Directories skipped during template scanning */
|
|
117
117
|
var TemplateSkipDir;
|
|
118
118
|
(function (TemplateSkipDir) {
|
|
119
119
|
TemplateSkipDir["PARTIALS"] = "partials";
|
|
120
120
|
TemplateSkipDir["TAG_DIR"] = "{tag}";
|
|
121
121
|
})(TemplateSkipDir || (exports.TemplateSkipDir = TemplateSkipDir = {}));
|
|
122
|
-
/**
|
|
122
|
+
/** Preset template names */
|
|
123
123
|
var PresetTemplateName;
|
|
124
124
|
(function (PresetTemplateName) {
|
|
125
125
|
PresetTemplateName["ALOVA"] = "alova";
|
|
@@ -130,26 +130,26 @@ var PresetTemplateName;
|
|
|
130
130
|
PresetTemplateName["CONFIG"] = "config";
|
|
131
131
|
PresetTemplateName["AI_DOC"] = "ai-doc";
|
|
132
132
|
})(PresetTemplateName || (exports.PresetTemplateName = PresetTemplateName = {}));
|
|
133
|
-
/**
|
|
133
|
+
/** Template directory name (differs from config.type: commonjs -> common) */
|
|
134
134
|
var ModuleTypeDir;
|
|
135
135
|
(function (ModuleTypeDir) {
|
|
136
136
|
ModuleTypeDir["TYPESCRIPT"] = "typescript";
|
|
137
137
|
ModuleTypeDir["MODULE"] = "module";
|
|
138
138
|
ModuleTypeDir["COMMON"] = "common";
|
|
139
139
|
})(ModuleTypeDir || (exports.ModuleTypeDir = ModuleTypeDir = {}));
|
|
140
|
-
/**
|
|
140
|
+
/** Array of module-type directory names */
|
|
141
141
|
exports.MODULE_TYPE_DIRS = [ModuleTypeDir.TYPESCRIPT, ModuleTypeDir.MODULE, ModuleTypeDir.COMMON];
|
|
142
|
-
/**
|
|
142
|
+
/** Module type -> ModuleKind mapping */
|
|
143
143
|
exports.MODULE_TYPE_TO_KIND = {
|
|
144
144
|
[TemplateTypeEnum.TYPESCRIPT]: ModuleKind.ES_MODULE,
|
|
145
145
|
[TemplateTypeEnum.MODULE]: ModuleKind.ES_MODULE,
|
|
146
146
|
[TemplateTypeEnum.COMMONJS]: ModuleKind.COMMON_JS,
|
|
147
147
|
};
|
|
148
|
-
/**
|
|
148
|
+
/** File extension -> output file name mapping */
|
|
149
149
|
function getTypeFileExtension(type) {
|
|
150
150
|
return type === TemplateTypeEnum.TYPESCRIPT ? FileExtension.TS : FileExtension.JS;
|
|
151
151
|
}
|
|
152
|
-
/**
|
|
152
|
+
/** Framework name list */
|
|
153
153
|
exports.FRAMEWORK_NAMES = [
|
|
154
154
|
FrameworkName.VUE,
|
|
155
155
|
FrameworkName.REACT,
|
|
@@ -16,7 +16,7 @@ function tupleTypeGenerator(ast, ctx) {
|
|
|
16
16
|
const spreadParam = ast.spreadParam ?? {
|
|
17
17
|
type: type_1.ASTType.ANY,
|
|
18
18
|
};
|
|
19
|
-
//
|
|
19
|
+
// for closed tuples (no extra items allowed), do not spread the rest param
|
|
20
20
|
const isClosed = spreadParam.type === type_1.ASTType.NEVER;
|
|
21
21
|
if (!isClosed) {
|
|
22
22
|
while (params.length < minItems) {
|
|
@@ -15,7 +15,7 @@ const removeRedundantKeywords_1 = __importDefault(require("./rules/removeRedunda
|
|
|
15
15
|
const simplifySingleType_1 = __importDefault(require("./rules/simplifySingleType"));
|
|
16
16
|
const validateSchema_1 = __importDefault(require("./rules/validateSchema"));
|
|
17
17
|
const normalizer = new normalizer_1.SchemaNormalizer();
|
|
18
|
-
// =================
|
|
18
|
+
// ================= Register rules =================
|
|
19
19
|
normalizer
|
|
20
20
|
.addRule({
|
|
21
21
|
name: 'inferType',
|
|
@@ -6,25 +6,25 @@ const utils_1 = require("../../../../utils");
|
|
|
6
6
|
class SchemaNormalizer {
|
|
7
7
|
rules = [];
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Add a new rule
|
|
10
10
|
*/
|
|
11
11
|
addRule(rule) {
|
|
12
12
|
this.rules.push(rule);
|
|
13
13
|
return this;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
* M1-A3:
|
|
16
|
+
* Normalize JSON Schema
|
|
17
|
+
* M1-A3: replaced JSON.stringify-based cycle detection with WeakSet, eliminating the O(s) serialization cost per node
|
|
18
18
|
*/
|
|
19
19
|
normalize(schema) {
|
|
20
|
-
//
|
|
20
|
+
// depth-first traversal
|
|
21
21
|
const visited = new WeakSet();
|
|
22
22
|
const process = (s) => {
|
|
23
23
|
if (!s || (0, utils_1.isReferenceObject)(s) || visited.has(s)) {
|
|
24
24
|
return s;
|
|
25
25
|
}
|
|
26
26
|
visited.add(s);
|
|
27
|
-
//
|
|
27
|
+
// process combinatory keywords
|
|
28
28
|
if (s.anyOf) {
|
|
29
29
|
s.anyOf = s.anyOf.map(item => process(item));
|
|
30
30
|
}
|
|
@@ -34,11 +34,11 @@ class SchemaNormalizer {
|
|
|
34
34
|
if (s.allOf) {
|
|
35
35
|
s.allOf = s.allOf.map(item => process(item));
|
|
36
36
|
}
|
|
37
|
-
//
|
|
37
|
+
// process array type
|
|
38
38
|
if ((0, utils_1.isMaybeArraySchemaObject)(s)) {
|
|
39
39
|
s.items = process(s.items);
|
|
40
40
|
}
|
|
41
|
-
//
|
|
41
|
+
// process object properties
|
|
42
42
|
if (s.properties) {
|
|
43
43
|
const newProps = {};
|
|
44
44
|
for (const [key, value] of Object.entries(s.properties)) {
|
|
@@ -47,7 +47,7 @@ class SchemaNormalizer {
|
|
|
47
47
|
s.properties = newProps;
|
|
48
48
|
}
|
|
49
49
|
let result = s;
|
|
50
|
-
//
|
|
50
|
+
// apply rules
|
|
51
51
|
for (const rule of this.rules) {
|
|
52
52
|
const newResult = rule.handler(result);
|
|
53
53
|
if (newResult && !visited.has(newResult)) {
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = mergeAnyOf;
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Detect whether two schemas form a discriminator on a shared property.
|
|
6
|
+
* When different branches use different const or enum values for the same field,
|
|
7
|
+
* merging them would lose the discriminant information, so they should be kept
|
|
8
|
+
* as separate union branches.
|
|
8
9
|
*/
|
|
9
10
|
function hasDiscriminatorConflict(a, b) {
|
|
10
11
|
const aProps = (a.properties ?? {});
|
|
@@ -15,15 +16,15 @@ function hasDiscriminatorConflict(a, b) {
|
|
|
15
16
|
}
|
|
16
17
|
const ap = aProps[key];
|
|
17
18
|
const bp = bProps[key];
|
|
18
|
-
//
|
|
19
|
+
// different const values -> discriminator
|
|
19
20
|
if (ap.const !== undefined && bp.const !== undefined && ap.const !== bp.const) {
|
|
20
21
|
return true;
|
|
21
22
|
}
|
|
22
|
-
//
|
|
23
|
+
// one const, one enum -> discriminator
|
|
23
24
|
if ((ap.const !== undefined && bp.enum) || (bp.const !== undefined && ap.enum)) {
|
|
24
25
|
return true;
|
|
25
26
|
}
|
|
26
|
-
//
|
|
27
|
+
// different enum values -> discriminator
|
|
27
28
|
if (ap.enum && bp.enum) {
|
|
28
29
|
const aKey = JSON.stringify([...ap.enum].sort());
|
|
29
30
|
const bKey = JSON.stringify([...bp.enum].sort());
|
|
@@ -35,7 +36,7 @@ function hasDiscriminatorConflict(a, b) {
|
|
|
35
36
|
return false;
|
|
36
37
|
}
|
|
37
38
|
/**
|
|
38
|
-
*
|
|
39
|
+
* A group is considered to have a conflict if any two of its branches have a discriminator conflict.
|
|
39
40
|
*/
|
|
40
41
|
function groupHasDiscriminatorConflict(group) {
|
|
41
42
|
for (let i = 0; i < group.length; i++) {
|
|
@@ -65,7 +66,7 @@ function mergeAnyOf(schema) {
|
|
|
65
66
|
mergedAnyOf.push(group[0]);
|
|
66
67
|
continue;
|
|
67
68
|
}
|
|
68
|
-
//
|
|
69
|
+
// if any discriminator conflict exists within the group, keep the original branches unmerged
|
|
69
70
|
if (groupHasDiscriminatorConflict(group)) {
|
|
70
71
|
mergedAnyOf.push(...group);
|
|
71
72
|
continue;
|
|
@@ -3,24 +3,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.default = normalizeCombiningKeywords;
|
|
4
4
|
function normalizeCombiningKeywords(schema) {
|
|
5
5
|
const { allOf, anyOf, oneOf, ...baseSchema } = schema;
|
|
6
|
-
//
|
|
6
|
+
// if there are no combinatory keywords, or only one of them exists, no processing is needed
|
|
7
7
|
if ([allOf, anyOf, oneOf].filter(Boolean).length <= 1) {
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
10
|
-
//
|
|
10
|
+
// store the final converted allOf array
|
|
11
11
|
const allOfArray = [];
|
|
12
|
-
// 2.
|
|
12
|
+
// 2. process the original allOf (spread into the new allOf)
|
|
13
13
|
if (Array.isArray(allOf)) {
|
|
14
14
|
allOfArray.push(...allOf);
|
|
15
15
|
}
|
|
16
|
-
// 3.
|
|
16
|
+
// 3. process anyOf (wrap into an anyOf object)
|
|
17
17
|
if (Array.isArray(anyOf) && anyOf.length > 0) {
|
|
18
18
|
allOfArray.push({ anyOf });
|
|
19
19
|
}
|
|
20
|
-
// 4.
|
|
20
|
+
// 4. process oneOf (wrap into a oneOf object)
|
|
21
21
|
if (Array.isArray(oneOf) && oneOf.length > 0) {
|
|
22
22
|
allOfArray.push({ oneOf });
|
|
23
23
|
}
|
|
24
|
-
//
|
|
24
|
+
// build the final schema
|
|
25
25
|
return allOfArray.length > 0 ? { allOf: allOfArray, ...baseSchema } : baseSchema;
|
|
26
26
|
}
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.default = normalizeNullType;
|
|
4
4
|
const NULL_TYPE = [null, 'null'];
|
|
5
5
|
function normalizeNullType(schema) {
|
|
6
|
-
//
|
|
6
|
+
// compatible with OpenAPI 3.0 nullable
|
|
7
7
|
if (schema.nullable) {
|
|
8
8
|
delete schema.nullable;
|
|
9
9
|
const currentType = schema.type || [];
|
|
@@ -4,15 +4,15 @@ exports.constTypeParser = constTypeParser;
|
|
|
4
4
|
const type_1 = require("../../../../type");
|
|
5
5
|
const utils_1 = require("./utils");
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Parse a JSON Schema with a const keyword into a literal AST node.
|
|
8
|
+
* For example:
|
|
9
9
|
* { "type": "string", "const": "email" } -> "email"
|
|
10
10
|
* { "type": "number", "const": 1 } -> 1
|
|
11
11
|
* { "const": true } -> true
|
|
12
12
|
* { "const": "authorization_code" } -> "authorization_code"
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
14
|
+
* Reference: JSON Schema draft-04+ allows `const` and `type` to appear together,
|
|
15
|
+
* meaning the field must equal the `const` value, which maps to a TypeScript literal type.
|
|
16
16
|
*/
|
|
17
17
|
function constTypeParser(schema, ctx) {
|
|
18
18
|
const result = {
|
|
@@ -14,16 +14,16 @@ function enumTypeParser(schema, ctx) {
|
|
|
14
14
|
};
|
|
15
15
|
const enumArray = schema.enum ?? [];
|
|
16
16
|
let typeArray = [schema.type ?? []].flat();
|
|
17
|
-
//
|
|
17
|
+
// if type is not specified, infer it from the enum values
|
|
18
18
|
if (typeArray.length === 0 && enumArray.length > 0) {
|
|
19
19
|
typeArray = [...new Set(enumArray.map(item => (0, utils_1.getType)(item)))];
|
|
20
20
|
}
|
|
21
|
-
//
|
|
21
|
+
// type compatibility check function
|
|
22
22
|
const isTypeCompatible = (itemType, allowedTypes) => {
|
|
23
23
|
return allowedTypes.includes(itemType)
|
|
24
24
|
|| (allowedTypes.includes('number') && itemType === 'integer');
|
|
25
25
|
};
|
|
26
|
-
//
|
|
26
|
+
// validate the type of all enum values
|
|
27
27
|
const hasInvalidType = enumArray.some(item => !isTypeCompatible((0, utils_1.getType)(item), typeArray));
|
|
28
28
|
if (hasInvalidType) {
|
|
29
29
|
throw helper_1.logger.throwError(`enum ${schema.title ?? 'undefined'} type error`, {
|
|
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const utils_1 = require("../../../../../utils");
|
|
4
4
|
exports.default = {
|
|
5
5
|
is(schema) {
|
|
6
|
-
//
|
|
7
|
-
// 1. type
|
|
8
|
-
// 2.
|
|
6
|
+
// check whether it is an array type
|
|
7
|
+
// 1. type is 'array'
|
|
8
|
+
// 2. or has an items field
|
|
9
9
|
return schema && (schema.type === 'array' || (0, utils_1.isMaybeArraySchemaObject)(schema));
|
|
10
10
|
},
|
|
11
11
|
to: 'array',
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Schemas with a const keyword are routed to the const parser first.
|
|
5
|
+
* This works even when the schema also declares a type (e.g. `{ "type": "string", "const": "email" }`),
|
|
6
|
+
* producing the correct literal type.
|
|
7
7
|
*/
|
|
8
8
|
exports.default = {
|
|
9
9
|
is(schema) {
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = {
|
|
4
4
|
is(schema) {
|
|
5
|
-
//
|
|
6
|
-
//
|
|
5
|
+
// check whether it is an enum type
|
|
6
|
+
// has an enum field that is a non-empty array
|
|
7
7
|
return schema && !!schema.enum && Array.isArray(schema.enum) && schema.enum.length > 0;
|
|
8
8
|
},
|
|
9
9
|
to: 'enum',
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = {
|
|
4
4
|
is(schema) {
|
|
5
|
-
//
|
|
6
|
-
// 1.
|
|
7
|
-
// 2.
|
|
8
|
-
// 3.
|
|
5
|
+
// check whether it is a combinatory type
|
|
6
|
+
// 1. has oneOf field (union type)
|
|
7
|
+
// 2. or has anyOf field (union type)
|
|
8
|
+
// 3. or has allOf field (intersection type)
|
|
9
9
|
return schema && (!!schema.oneOf || !!schema.anyOf || !!schema.allOf);
|
|
10
10
|
},
|
|
11
11
|
to: 'group',
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = {
|
|
4
4
|
is(schema) {
|
|
5
|
-
//
|
|
6
|
-
// 1. type
|
|
7
|
-
// 2.
|
|
8
|
-
// 3.
|
|
5
|
+
// check whether it is an object type
|
|
6
|
+
// 1. type is 'object'
|
|
7
|
+
// 2. or has a properties field
|
|
8
|
+
// 3. or has an additionalProperties field
|
|
9
9
|
return schema && (schema.type === 'object' || !!schema.properties || !!schema.additionalProperties);
|
|
10
10
|
},
|
|
11
11
|
to: 'object',
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = {
|
|
4
4
|
is(schema) {
|
|
5
|
-
//
|
|
6
|
-
// 1. type
|
|
7
|
-
// 2.
|
|
5
|
+
// check whether it is a tuple type
|
|
6
|
+
// 1. type is 'array'
|
|
7
|
+
// 2. items is an array (legacy JSON Schema tuple syntax) or prefixItems exists (OpenAPI 3.1 / JSON Schema 2020-12 tuple syntax)
|
|
8
8
|
if (!schema)
|
|
9
9
|
return false;
|
|
10
10
|
const tuple = schema;
|
|
@@ -5,12 +5,12 @@ const helper_1 = require("../../../../helper");
|
|
|
5
5
|
const type_1 = require("../../../../type");
|
|
6
6
|
const utils_1 = require("./utils");
|
|
7
7
|
function tupleTypeParser(schema, ctx) {
|
|
8
|
-
// OpenAPI 3.1 / JSON Schema 2020-12
|
|
8
|
+
// OpenAPI 3.1 / JSON Schema 2020-12 uses prefixItems for positional elements, with legacy array-style items supported
|
|
9
9
|
const elementSchemas = (Array.isArray(schema.prefixItems)
|
|
10
10
|
? schema.prefixItems
|
|
11
11
|
: (Array.isArray(schema.items) ? schema.items : []));
|
|
12
12
|
const params = elementSchemas.map(item => ctx.next(item, ctx.options));
|
|
13
|
-
// 2020-12
|
|
13
|
+
// 2020-12: a single items denotes the "rest items" type; items:false / additionalItems:false forbids extra items
|
|
14
14
|
let spreadParam;
|
|
15
15
|
if (schema.items && !Array.isArray(schema.items)) {
|
|
16
16
|
spreadParam = ctx.next(schema.items, ctx.options);
|
|
@@ -78,7 +78,7 @@ function splitIntoWords(str) {
|
|
|
78
78
|
const char = str[i];
|
|
79
79
|
const lastChar = str[i - 1] ?? '';
|
|
80
80
|
const nextChar = str[i + 1] ?? '';
|
|
81
|
-
//
|
|
81
|
+
// if a non-word character is encountered, end the current word
|
|
82
82
|
if (/[^\w$]/.test(char) || ['_'].includes(char)) {
|
|
83
83
|
if (currentWord) {
|
|
84
84
|
words.push(currentWord);
|
|
@@ -115,13 +115,13 @@ async function parseRequestBody(requestBody, options) {
|
|
|
115
115
|
}
|
|
116
116
|
function getContentKey(content = {}, requireKey = 'application/json') {
|
|
117
117
|
const requireKeys = Array.isArray(requireKey) ? requireKey : [requireKey];
|
|
118
|
-
//
|
|
118
|
+
// search for an existing mediaType in array order
|
|
119
119
|
for (const key of requireKeys) {
|
|
120
120
|
if (content[key]) {
|
|
121
121
|
return key;
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
|
-
//
|
|
124
|
+
// if none exists, return the first key or the default value
|
|
125
125
|
return Object.keys(content)[0] || requireKeys[0];
|
|
126
126
|
}
|
|
127
127
|
async function parseParameters(parameters, options) {
|
|
@@ -213,7 +213,7 @@ async function transformApiMethods(apiMethod, options) {
|
|
|
213
213
|
return apiMethod;
|
|
214
214
|
}
|
|
215
215
|
const { apiDescriptor, apiInfo } = apiMethod2ApiDescriptor(apiMethod, options);
|
|
216
|
-
// M2-B1: apiDescriptor
|
|
216
|
+
// M2-B1: apiDescriptor comes from apiMethod2ApiDescriptor which already did cloneDeep, no second clone needed
|
|
217
217
|
let newApiDescriptor = apiDescriptor;
|
|
218
218
|
try {
|
|
219
219
|
newApiDescriptor = handleApi(newApiDescriptor);
|
|
@@ -241,7 +241,7 @@ async function transformApiMethods(apiMethod, options) {
|
|
|
241
241
|
function apiMethod2ApiDescriptor(apiMethod, options) {
|
|
242
242
|
const { url, method } = apiMethod;
|
|
243
243
|
const { document, config } = options;
|
|
244
|
-
//
|
|
244
|
+
// deep copy required: handleApi may mutate nested fields like tags/security; a shallow copy would pollute the original operationObject
|
|
245
245
|
const operationObject = (0, lodash_1.cloneDeep)(apiMethod.operationObject);
|
|
246
246
|
const { requestBody, responses, parameters } = operationObject;
|
|
247
247
|
const apiDescriptor = {
|
|
@@ -292,7 +292,7 @@ function apiMethod2ApiDescriptor(apiMethod, options) {
|
|
|
292
292
|
}
|
|
293
293
|
function apiDescriptor2apiMethod(apiDescriptor, options) {
|
|
294
294
|
const apiDescriptorValue = { ...apiDescriptor };
|
|
295
|
-
const operationObject = (0, lodash_1.cloneDeep)(options.operationObject); //
|
|
295
|
+
const operationObject = (0, lodash_1.cloneDeep)(options.operationObject); // still needs deep copy: deep-path assignments like content[key].schema are written back via mergeObject
|
|
296
296
|
const { url, method } = apiDescriptorValue;
|
|
297
297
|
const { successKey, requestKey, responseKey, hasResponse, hasParameters, hasRequestBody, requestBody, response } = options.oldApiInfo;
|
|
298
298
|
if (!(0, lodash_1.isEmpty)(apiDescriptorValue.requestBody) || hasRequestBody) {
|
|
@@ -47,7 +47,7 @@ const helper_1 = require("../../../helper");
|
|
|
47
47
|
const document_1 = require("../../../helper/document");
|
|
48
48
|
const openapi_1 = require("../../../utils/openapi");
|
|
49
49
|
const helper_2 = require("./helper");
|
|
50
|
-
/** M2-B4:
|
|
50
|
+
/** M2-B4: lightweight concurrency limiter, no extra dependencies */
|
|
51
51
|
async function pMap(items, fn, concurrency) {
|
|
52
52
|
const results = Array.from({ length: items.length });
|
|
53
53
|
let idx = 0;
|
|
@@ -60,7 +60,7 @@ async function pMap(items, fn, concurrency) {
|
|
|
60
60
|
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
|
|
61
61
|
return results;
|
|
62
62
|
}
|
|
63
|
-
/**
|
|
63
|
+
/** Automatically compute a reasonable concurrency limit based on CPU core count */
|
|
64
64
|
function autoConcurrency() {
|
|
65
65
|
const cpuCount = Math.max(1, (0, node_os_1.cpus)().length);
|
|
66
66
|
return Math.min(64, Math.max(8, cpuCount * 4));
|
|
@@ -71,7 +71,7 @@ class TemplateParser {
|
|
|
71
71
|
operationIdSet = new Set();
|
|
72
72
|
pathMap = [];
|
|
73
73
|
refNameMap = new Map();
|
|
74
|
-
/** M1-A4:
|
|
74
|
+
/** M1-A4: replaced tagedApis.find() linear lookup with a Map index, O(n·t) → O(n+t) */
|
|
75
75
|
tagMap = new Map();
|
|
76
76
|
document;
|
|
77
77
|
options;
|
|
@@ -146,9 +146,11 @@ class TemplateParser {
|
|
|
146
146
|
const tsWp = node_path_1.default.resolve(__dirname, '../../workerPool/worker.ts');
|
|
147
147
|
const { existsSync: fex } = await Promise.resolve().then(() => __importStar(require('node:fs')));
|
|
148
148
|
const workerScript = fex(jsWp) ? jsWp : tsWp;
|
|
149
|
-
//
|
|
149
|
+
// Reuse workers only within the same generator output. The workerData document is immutable after spawn,
|
|
150
|
+
// so generators in the same project must not share a pool.
|
|
151
|
+
const outputDir = node_path_1.default.resolve(this.options.projectPath, this.options.generatorConfig.output);
|
|
150
152
|
const pool = poolManager_1.PoolManager.getInstance().get({
|
|
151
|
-
key: `schemaWorker_${
|
|
153
|
+
key: `schemaWorker_${outputDir}`,
|
|
152
154
|
workerScript,
|
|
153
155
|
sharedContext: {
|
|
154
156
|
document: this.document,
|
|
@@ -173,7 +175,7 @@ class TemplateParser {
|
|
|
173
175
|
});
|
|
174
176
|
templateData.components = [...new Set(this.schemasMap.values())];
|
|
175
177
|
templateData.componentNames = [...this.schemasMap.keys()];
|
|
176
|
-
//
|
|
178
|
+
// sort by name lexicographically to ensure deterministic output order (avoid Map insertion-order drift under concurrency)
|
|
177
179
|
const sorted = [...this.schemasMap.entries()].sort(([a], [b]) => a.localeCompare(b));
|
|
178
180
|
templateData.componentNames = sorted.map(([k]) => k);
|
|
179
181
|
templateData.components = sorted.map(([, v]) => v);
|
|
@@ -301,7 +303,7 @@ class TemplateParser {
|
|
|
301
303
|
let tagApis = this.tagMap.get(api.tag);
|
|
302
304
|
if (!tagApis) {
|
|
303
305
|
tagApis = {
|
|
304
|
-
|
|
306
|
+
tag: api.tag,
|
|
305
307
|
apis: [],
|
|
306
308
|
};
|
|
307
309
|
this.tagMap.set(api.tag, tagApis);
|
|
@@ -77,10 +77,10 @@ function computePerTagHashes(allApis, tagedApis) {
|
|
|
77
77
|
const allHashes = [];
|
|
78
78
|
if (tagedApis) {
|
|
79
79
|
// P2: Use pre-grouped tagedApis to avoid O(n) re-grouping loop
|
|
80
|
-
for (const {
|
|
80
|
+
for (const { tag, apis: groupApis } of tagedApis) {
|
|
81
81
|
const hashes = groupApis.map(computeApiHash).sort();
|
|
82
82
|
allHashes.push(...hashes);
|
|
83
|
-
tags[
|
|
83
|
+
tags[tag] = (0, node_crypto_1.createHash)('sha256').update(hashes.join('')).digest('hex').slice(0, 16);
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
else {
|