wormajs 0.0.1
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/LICENSE +21 -0
- package/README.md +49 -0
- package/dist/bin/actions.js +245 -0
- package/dist/bin/cli.js +27 -0
- package/dist/bin/progressRenderer.js +47 -0
- package/dist/bin/renderer.js +551 -0
- package/dist/bin/theme.js +26 -0
- package/dist/config.js +19 -0
- package/dist/constant.js +162 -0
- package/dist/core/WorkerPool.js +102 -0
- package/dist/core/loader/astLoader/generates/array.js +34 -0
- package/dist/core/loader/astLoader/generates/enum.js +61 -0
- package/dist/core/loader/astLoader/generates/group.js +41 -0
- package/dist/core/loader/astLoader/generates/index.js +71 -0
- package/dist/core/loader/astLoader/generates/interface.js +59 -0
- package/dist/core/loader/astLoader/generates/simple.js +67 -0
- package/dist/core/loader/astLoader/generates/tuple.js +54 -0
- package/dist/core/loader/astLoader/generates/type.js +2 -0
- package/dist/core/loader/astLoader/generates/utils.js +86 -0
- package/dist/core/loader/astLoader/helper.js +21 -0
- package/dist/core/loader/astLoader/index.js +24 -0
- package/dist/core/loader/astLoader/normalize/index.js +70 -0
- package/dist/core/loader/astLoader/normalize/normalizer.js +69 -0
- package/dist/core/loader/astLoader/normalize/rules/convertTypeArray.js +68 -0
- package/dist/core/loader/astLoader/normalize/rules/handleEmptyType.js +8 -0
- package/dist/core/loader/astLoader/normalize/rules/inferType.js +43 -0
- package/dist/core/loader/astLoader/normalize/rules/mergeAnyOf.js +45 -0
- package/dist/core/loader/astLoader/normalize/rules/normalizeCombiningKeywords.js +26 -0
- package/dist/core/loader/astLoader/normalize/rules/normalizeEnum.js +38 -0
- package/dist/core/loader/astLoader/normalize/rules/normalizeNullType.js +24 -0
- package/dist/core/loader/astLoader/normalize/rules/removeRedundantKeywords.js +27 -0
- package/dist/core/loader/astLoader/normalize/rules/simplifySingleType.js +8 -0
- package/dist/core/loader/astLoader/normalize/rules/validateSchema.js +14 -0
- package/dist/core/loader/astLoader/parsers/array.js +28 -0
- package/dist/core/loader/astLoader/parsers/enum.js +49 -0
- package/dist/core/loader/astLoader/parsers/forward/array.js +12 -0
- package/dist/core/loader/astLoader/parsers/forward/enum.js +10 -0
- package/dist/core/loader/astLoader/parsers/forward/group.js +12 -0
- package/dist/core/loader/astLoader/parsers/forward/index.js +20 -0
- package/dist/core/loader/astLoader/parsers/forward/object.js +12 -0
- package/dist/core/loader/astLoader/parsers/forward/tuple.js +11 -0
- package/dist/core/loader/astLoader/parsers/forward/type.js +2 -0
- package/dist/core/loader/astLoader/parsers/group.js +50 -0
- package/dist/core/loader/astLoader/parsers/index.js +66 -0
- package/dist/core/loader/astLoader/parsers/object.js +44 -0
- package/dist/core/loader/astLoader/parsers/reference.js +41 -0
- package/dist/core/loader/astLoader/parsers/simple.js +48 -0
- package/dist/core/loader/astLoader/parsers/tuple.js +36 -0
- package/dist/core/loader/astLoader/parsers/type.js +2 -0
- package/dist/core/loader/astLoader/parsers/utils.js +58 -0
- package/dist/core/loader/callingCodeLoader/helper.js +183 -0
- package/dist/core/loader/callingCodeLoader/index.js +40 -0
- package/dist/core/loader/index.js +20 -0
- package/dist/core/loader/schemaLoader/index.js +101 -0
- package/dist/core/loader/standardLoader/helper.js +142 -0
- package/dist/core/loader/standardLoader/index.js +38 -0
- package/dist/core/loader/standardLoader/standards.js +105 -0
- package/dist/core/parser/index.js +18 -0
- package/dist/core/parser/openApiParser/helper.js +165 -0
- package/dist/core/parser/openApiParser/index.js +14 -0
- package/dist/core/parser/templateParser/helper.js +333 -0
- package/dist/core/parser/templateParser/index.js +314 -0
- package/dist/core/workerPool/index.js +6 -0
- package/dist/core/workerPool/poolManager.js +45 -0
- package/dist/core/workerPool/swagger2Worker.js +24 -0
- package/dist/core/workerPool/worker.js +61 -0
- package/dist/createConfig.js +37 -0
- package/dist/defineConfig.js +6 -0
- package/dist/functions/getAutoTemplateType.js +37 -0
- package/dist/functions/getFrameworkTag.js +18 -0
- package/dist/functions/prepareConfig.js +41 -0
- package/dist/functions/readWormaRc.js +155 -0
- package/dist/functions/wormaJson.js +232 -0
- package/dist/generate.js +84 -0
- package/dist/helper/PluginDriver.js +98 -0
- package/dist/helper/comment.js +88 -0
- package/dist/helper/config/ConfigHelper.js +79 -0
- package/dist/helper/config/ConfigManager.js +88 -0
- package/dist/helper/config/GeneratorHelper.js +343 -0
- package/dist/helper/config/index.js +19 -0
- package/dist/helper/config/type.js +2 -0
- package/dist/helper/config/zType.js +170 -0
- package/dist/helper/document/index.js +160 -0
- package/dist/helper/index.js +23 -0
- package/dist/helper/logger/index.js +76 -0
- package/dist/helper/progress.js +66 -0
- package/dist/helper/template/index.js +475 -0
- package/dist/index.js +33 -0
- package/dist/plugins/createPlugin.js +30 -0
- package/dist/plugins/index.js +34 -0
- package/dist/plugins/presets/aiDoc.js +173 -0
- package/dist/plugins/presets/apifox.js +56 -0
- package/dist/plugins/presets/filterApi.js +129 -0
- package/dist/plugins/presets/importType.js +49 -0
- package/dist/plugins/presets/payloadModifier/hepler.js +195 -0
- package/dist/plugins/presets/payloadModifier/index.js +122 -0
- package/dist/plugins/presets/payloadModifier/type.js +2 -0
- package/dist/plugins/presets/platform.js +73 -0
- package/dist/plugins/presets/rename.js +209 -0
- package/dist/plugins/presets/tagModifier.js +104 -0
- package/dist/plugins/presets/utils.js +36 -0
- package/dist/readConfig.js +92 -0
- package/dist/resolveWorkspaces.js +83 -0
- package/dist/template/index.js +180 -0
- package/dist/template/presets/ai-doc/SKILL.md.handlebars +29 -0
- package/dist/template/presets/ai-doc/references/{tag}/{api}.md.handlebars +54 -0
- package/dist/template/presets/alova/common/#index.cjs.handlebars +12 -0
- package/dist/template/presets/alova/common/components.d.cts.handlebars +1 -0
- package/dist/template/presets/alova/common/helper.cjs.handlebars +13 -0
- package/dist/template/presets/alova/common/services/#index.cjs.handlebars +13 -0
- package/dist/template/presets/alova/common/services/{tag}.cjs.handlebars +28 -0
- package/dist/template/presets/alova/common/services/{tag}.d.cts.handlebars +15 -0
- package/dist/template/presets/alova/common/typed.d.cts.handlebars +1 -0
- package/dist/template/presets/alova/module/#index.js.handlebars +12 -0
- package/dist/template/presets/alova/module/components.d.ts.handlebars +1 -0
- package/dist/template/presets/alova/module/helper.js.handlebars +11 -0
- package/dist/template/presets/alova/module/services/#index.js.handlebars +9 -0
- package/dist/template/presets/alova/module/services/{tag}.d.ts.handlebars +15 -0
- package/dist/template/presets/alova/module/services/{tag}.js.handlebars +21 -0
- package/dist/template/presets/alova/module/typed.d.ts.handlebars +1 -0
- package/dist/template/presets/alova/partials/api-jsdoc.handlebars +44 -0
- package/dist/template/presets/alova/partials/build-payload-body.handlebars +22 -0
- package/dist/template/presets/alova/partials/comment.handlebars +19 -0
- package/dist/template/presets/alova/partials/components-body.handlebars +4 -0
- package/dist/template/presets/alova/partials/dts-extra-config.handlebars +8 -0
- package/dist/template/presets/alova/partials/dts-fn-declare.handlebars +1 -0
- package/dist/template/presets/alova/partials/extract-responded.handlebars +11 -0
- package/dist/template/presets/alova/partials/stateshook-import.handlebars +9 -0
- package/dist/template/presets/alova/partials/stateshook-option.handlebars +9 -0
- package/dist/template/presets/alova/partials/typed-body.handlebars +43 -0
- package/dist/template/presets/alova/typescript/#index.ts.handlebars +14 -0
- package/dist/template/presets/alova/typescript/components.d.ts.handlebars +1 -0
- package/dist/template/presets/alova/typescript/helper.ts.handlebars +9 -0
- package/dist/template/presets/alova/typescript/services/#index.ts.handlebars +9 -0
- package/dist/template/presets/alova/typescript/services/{tag}.ts.handlebars +35 -0
- package/dist/template/presets/alova/typescript/typed.ts.handlebars +1 -0
- package/dist/template/presets/alova-globals/common/#index.cjs.handlebars +41 -0
- package/dist/template/presets/alova-globals/common/apiDefinitions.cjs.handlebars +12 -0
- package/dist/template/presets/alova-globals/common/createApis.cjs.handlebars +48 -0
- package/dist/template/presets/alova-globals/common/globals.d.cts.handlebars +2 -0
- package/dist/template/presets/alova-globals/module/#index.js.handlebars +2 -0
- package/dist/template/presets/alova-globals/module/apiDefinitions.js.handlebars +12 -0
- package/dist/template/presets/alova-globals/module/createApis.js.handlebars +44 -0
- package/dist/template/presets/alova-globals/module/globals.d.ts.handlebars +2 -0
- package/dist/template/presets/alova-globals/partials/comment.handlebars +19 -0
- package/dist/template/presets/alova-globals/partials/createApis-proxy-js.handlebars +55 -0
- package/dist/template/presets/alova-globals/partials/globals-d-ts.handlebars +148 -0
- package/dist/template/presets/alova-globals/partials/index-esm.handlebars +38 -0
- package/dist/template/presets/alova-globals/partials/withConfigType-jsdoc.handlebars +22 -0
- package/dist/template/presets/alova-globals/typescript/#index.ts.handlebars +2 -0
- package/dist/template/presets/alova-globals/typescript/apiDefinitions.ts.handlebars +12 -0
- package/dist/template/presets/alova-globals/typescript/createApis.ts.handlebars +99 -0
- package/dist/template/presets/alova-globals/typescript/globals.d.ts.handlebars +2 -0
- package/dist/template/presets/axios/common/#index.cjs.handlebars +22 -0
- package/dist/template/presets/axios/common/components.d.cts.handlebars +1 -0
- package/dist/template/presets/axios/common/helper.cjs.handlebars +27 -0
- package/dist/template/presets/axios/common/services/#index.cjs.handlebars +13 -0
- package/dist/template/presets/axios/common/services/{tag}.cjs.handlebars +28 -0
- package/dist/template/presets/axios/common/services/{tag}.d.cts.handlebars +11 -0
- package/dist/template/presets/axios/module/#index.js.handlebars +20 -0
- package/dist/template/presets/axios/module/components.d.ts.handlebars +1 -0
- package/dist/template/presets/axios/module/helper.js.handlebars +25 -0
- package/dist/template/presets/axios/module/services/#index.js.handlebars +9 -0
- package/dist/template/presets/axios/module/services/{tag}.d.ts.handlebars +11 -0
- package/dist/template/presets/axios/module/services/{tag}.js.handlebars +20 -0
- package/dist/template/presets/axios/partials/api-jsdoc.handlebars +44 -0
- package/dist/template/presets/axios/partials/comment.handlebars +19 -0
- package/dist/template/presets/axios/partials/components-body.handlebars +4 -0
- package/dist/template/presets/axios/partials/dts-fn-declare.handlebars +1 -0
- package/dist/template/presets/axios/partials/dts-types.handlebars +7 -0
- package/dist/template/presets/axios/typescript/#index.ts.handlebars +20 -0
- package/dist/template/presets/axios/typescript/components.d.ts.handlebars +1 -0
- package/dist/template/presets/axios/typescript/helper.ts.handlebars +28 -0
- package/dist/template/presets/axios/typescript/services/#index.ts.handlebars +9 -0
- package/dist/template/presets/axios/typescript/services/{tag}.ts.handlebars +31 -0
- package/dist/template/presets/config/common/worma.config.js.handlebars +9 -0
- package/dist/template/presets/config/module/worma.config.js.handlebars +9 -0
- package/dist/template/presets/config/partials/generator-content.handlebars +45 -0
- package/dist/template/presets/config/typescript/worma.config.ts.handlebars +9 -0
- package/dist/template/presets/fetch/common/#index.cjs.handlebars +17 -0
- package/dist/template/presets/fetch/common/FetchClient.cjs.handlebars +48 -0
- package/dist/template/presets/fetch/common/components.d.cts.handlebars +1 -0
- package/dist/template/presets/fetch/common/helper.cjs.handlebars +27 -0
- package/dist/template/presets/fetch/common/services/#index.cjs.handlebars +13 -0
- package/dist/template/presets/fetch/common/services/{tag}.cjs.handlebars +23 -0
- package/dist/template/presets/fetch/common/services/{tag}.d.cts.handlebars +10 -0
- package/dist/template/presets/fetch/module/#index.js.handlebars +15 -0
- package/dist/template/presets/fetch/module/FetchClient.js.handlebars +46 -0
- package/dist/template/presets/fetch/module/components.d.ts.handlebars +1 -0
- package/dist/template/presets/fetch/module/helper.js.handlebars +25 -0
- package/dist/template/presets/fetch/module/services/#index.js.handlebars +9 -0
- package/dist/template/presets/fetch/module/services/{tag}.d.ts.handlebars +10 -0
- package/dist/template/presets/fetch/module/services/{tag}.js.handlebars +15 -0
- package/dist/template/presets/fetch/partials/api-jsdoc.handlebars +44 -0
- package/dist/template/presets/fetch/partials/comment.handlebars +19 -0
- package/dist/template/presets/fetch/partials/components-body.handlebars +4 -0
- package/dist/template/presets/fetch/partials/dts-fn-declare.handlebars +1 -0
- package/dist/template/presets/fetch/partials/dts-types.handlebars +7 -0
- package/dist/template/presets/fetch/typescript/#index.ts.handlebars +15 -0
- package/dist/template/presets/fetch/typescript/FetchClient.ts.handlebars +59 -0
- package/dist/template/presets/fetch/typescript/components.d.ts.handlebars +1 -0
- package/dist/template/presets/fetch/typescript/helper.ts.handlebars +28 -0
- package/dist/template/presets/fetch/typescript/services/#index.ts.handlebars +9 -0
- package/dist/template/presets/fetch/typescript/services/{tag}.ts.handlebars +25 -0
- package/dist/template/presets/ky/module/#index.js.handlebars +14 -0
- package/dist/template/presets/ky/module/components.d.ts.handlebars +1 -0
- package/dist/template/presets/ky/module/helper.js.handlebars +27 -0
- package/dist/template/presets/ky/module/services/#index.js.handlebars +9 -0
- package/dist/template/presets/ky/module/services/{tag}.d.ts.handlebars +11 -0
- package/dist/template/presets/ky/module/services/{tag}.js.handlebars +19 -0
- package/dist/template/presets/ky/partials/api-jsdoc.handlebars +44 -0
- package/dist/template/presets/ky/partials/comment.handlebars +19 -0
- package/dist/template/presets/ky/partials/components-body.handlebars +4 -0
- package/dist/template/presets/ky/partials/dts-fn-declare.handlebars +1 -0
- package/dist/template/presets/ky/partials/dts-types.handlebars +9 -0
- package/dist/template/presets/ky/typescript/#index.ts.handlebars +14 -0
- package/dist/template/presets/ky/typescript/components.d.ts.handlebars +1 -0
- package/dist/template/presets/ky/typescript/helper.ts.handlebars +30 -0
- package/dist/template/presets/ky/typescript/services/#index.ts.handlebars +9 -0
- package/dist/template/presets/ky/typescript/services/{tag}.ts.handlebars +30 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/type/api.js +14 -0
- package/dist/type/ast.js +24 -0
- package/dist/type/base.js +17 -0
- package/dist/type/index.js +20 -0
- package/dist/type/lib.js +17 -0
- package/dist/type/openapi.js +2 -0
- package/dist/utils/base.js +212 -0
- package/dist/utils/format.js +64 -0
- package/dist/utils/index.js +21 -0
- package/dist/utils/openapi.js +417 -0
- package/dist/utils/readPackageJson.js +35 -0
- package/dist/utils/template.js +93 -0
- package/package.json +88 -0
- package/typings/index.d.ts +512 -0
- package/typings/plugins.d.ts +727 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.aiDoc = aiDoc;
|
|
7
|
+
const node_child_process_1 = require("node:child_process");
|
|
8
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
|
+
const node_module_1 = require("node:module");
|
|
10
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
11
|
+
const constant_1 = require("../../constant");
|
|
12
|
+
const logger_1 = require("../../helper/logger");
|
|
13
|
+
const template_1 = require("../../template");
|
|
14
|
+
const nodeRequire = (0, node_module_1.createRequire)(__filename);
|
|
15
|
+
const SKILLS_SUPPORTED_AGENTS_URL = 'https://www.npmjs.com/package/skills#supported-agents';
|
|
16
|
+
const prefix = '[plugin: aiDoc]';
|
|
17
|
+
function aiDoc(config) {
|
|
18
|
+
const outputDirName = config?.outputDir ?? 'aidocs';
|
|
19
|
+
const customTemplatePath = config?.template;
|
|
20
|
+
const installSkillEnabled = config?.installSkill ?? false;
|
|
21
|
+
let capturedOutput = '';
|
|
22
|
+
let capturedServerName = '';
|
|
23
|
+
return {
|
|
24
|
+
name: constant_1.PluginName.AI_DOC,
|
|
25
|
+
config({ config: generatorConfig }) {
|
|
26
|
+
capturedOutput = generatorConfig.output ?? '';
|
|
27
|
+
capturedServerName = generatorConfig.serverName ?? '';
|
|
28
|
+
return generatorConfig;
|
|
29
|
+
},
|
|
30
|
+
async codeGenerated({ error, data: templateData, projectPath, outputDir, renderTemplate }) {
|
|
31
|
+
if (error)
|
|
32
|
+
return;
|
|
33
|
+
if (!templateData)
|
|
34
|
+
return;
|
|
35
|
+
const outputBase = outputDir || node_path_1.default.resolve(projectPath, capturedOutput);
|
|
36
|
+
const aidocsDir = node_path_1.default.resolve(outputBase, outputDirName);
|
|
37
|
+
const templatePath = customTemplatePath
|
|
38
|
+
? (node_path_1.default.isAbsolute(customTemplatePath) ? customTemplatePath : node_path_1.default.resolve(projectPath, customTemplatePath))
|
|
39
|
+
: (0, template_1.getPresetTemplatePath)(constant_1.PresetTemplateName.AI_DOC);
|
|
40
|
+
const serverName = capturedServerName || templateData.title || 'API';
|
|
41
|
+
// Compute file location for each API (relative path from project root to generated file)
|
|
42
|
+
// Skip fileLocation for alova-globals since APIs are called globally, not from a specific file
|
|
43
|
+
const isGlobals = templateData.config?.templateName === 'alova-globals';
|
|
44
|
+
const outputRel = node_path_1.default.relative(projectPath, outputBase);
|
|
45
|
+
const enrichedData = {
|
|
46
|
+
...templateData,
|
|
47
|
+
allApis: templateData.allApis.map(api => ({
|
|
48
|
+
...api,
|
|
49
|
+
// Store the generated file location where this API's code lives
|
|
50
|
+
...(isGlobals ? {} : { fileLocation: `${outputRel.replace(/\\/g, '/')}/${api.tag}` }),
|
|
51
|
+
})),
|
|
52
|
+
tagedApis: templateData.tagedApis.map(group => ({
|
|
53
|
+
...group,
|
|
54
|
+
apis: group.apis.map(api => ({
|
|
55
|
+
...api,
|
|
56
|
+
...(isGlobals ? {} : { fileLocation: `${outputRel.replace(/\\/g, '/')}/${group.tagName}` }),
|
|
57
|
+
})),
|
|
58
|
+
})),
|
|
59
|
+
};
|
|
60
|
+
await renderTemplate?.({
|
|
61
|
+
templatePath,
|
|
62
|
+
type: templateData.type,
|
|
63
|
+
outputDir: aidocsDir,
|
|
64
|
+
data: {
|
|
65
|
+
...enrichedData,
|
|
66
|
+
serverName,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
if (installSkillEnabled) {
|
|
70
|
+
const { agent } = resolveAgent(projectPath);
|
|
71
|
+
installSkill(aidocsDir, agent, projectPath);
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Resolve the target coding agent from `.env.local` in the project root.
|
|
78
|
+
*
|
|
79
|
+
* If the file does not exist, it will be created and `.gitignore` will be
|
|
80
|
+
* updated to ignore `*.local` files. An error is then thrown asking the user
|
|
81
|
+
* to set `agent=<coding-agent>`.
|
|
82
|
+
*
|
|
83
|
+
* If `agent` is missing, an error is thrown with guidance.
|
|
84
|
+
*/
|
|
85
|
+
function resolveAgent(projectPath) {
|
|
86
|
+
const envFilePath = node_path_1.default.join(projectPath, '.env.local');
|
|
87
|
+
if (!node_fs_1.default.existsSync(envFilePath)) {
|
|
88
|
+
createEnvLocalFile(envFilePath);
|
|
89
|
+
ensureGitIgnoreLocal(projectPath);
|
|
90
|
+
throw logger_1.logger.throwError(`${prefix}Created .env.local at project root. Please set the coding agent you are using, e.g. agent=cursor. Supported agents list: ${SKILLS_SUPPORTED_AGENTS_URL}`);
|
|
91
|
+
}
|
|
92
|
+
const content = node_fs_1.default.readFileSync(envFilePath, 'utf-8');
|
|
93
|
+
const agent = parseEnvValue(content, 'agent');
|
|
94
|
+
if (!agent) {
|
|
95
|
+
throw logger_1.logger.throwError(`${prefix}Missing "agent" in .env.local at project root. Please set the coding agent you are using, e.g. agent=cursor. Supported agents list: ${SKILLS_SUPPORTED_AGENTS_URL}`);
|
|
96
|
+
}
|
|
97
|
+
return { agent };
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Resolve the absolute path to the `skills` CLI installed alongside this package.
|
|
101
|
+
*/
|
|
102
|
+
function resolveSkillsCli() {
|
|
103
|
+
try {
|
|
104
|
+
const skillsPkgPath = nodeRequire.resolve('skills/package.json');
|
|
105
|
+
return node_path_1.default.join(node_path_1.default.dirname(skillsPkgPath), 'bin', 'cli.mjs');
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
throw logger_1.logger.throwError('Could not resolve the "skills" CLI. Make sure "skills" is installed as a dependency of @alova/worma.');
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Install the generated skill into the configured coding agent using the
|
|
113
|
+
* `skills` CLI.
|
|
114
|
+
*/
|
|
115
|
+
function installSkill(skillPath, agent, projectPath) {
|
|
116
|
+
// Normalize to forward slashes so the shell command works across platforms
|
|
117
|
+
const resolvedSkillPath = node_path_1.default.resolve(skillPath).replace(/\\/g, '/');
|
|
118
|
+
const skillsCli = resolveSkillsCli();
|
|
119
|
+
try {
|
|
120
|
+
(0, node_child_process_1.execSync)(`node "${skillsCli}" add "${resolvedSkillPath}" -a "${agent}" -y`, {
|
|
121
|
+
cwd: projectPath,
|
|
122
|
+
stdio: 'pipe',
|
|
123
|
+
encoding: 'utf-8',
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
console.error(`${prefix}Failed to install skill to "${agent}". Make sure the skill is valid and the target agent is supported.`, error.stack);
|
|
128
|
+
throw logger_1.logger.throwError(error);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
function createEnvLocalFile(envFilePath) {
|
|
132
|
+
const content = `# Worma aiDoc skill installer configuration
|
|
133
|
+
# Please set the coding agent you are using (e.g. cursor, claude-code, windsurf).
|
|
134
|
+
# Supported agents list: ${SKILLS_SUPPORTED_AGENTS_URL}
|
|
135
|
+
agent=
|
|
136
|
+
`;
|
|
137
|
+
node_fs_1.default.writeFileSync(envFilePath, content, 'utf-8');
|
|
138
|
+
}
|
|
139
|
+
function ensureGitIgnoreLocal(projectPath) {
|
|
140
|
+
const gitignorePath = node_path_1.default.join(projectPath, '.gitignore');
|
|
141
|
+
const pattern = '*.local';
|
|
142
|
+
let content = '';
|
|
143
|
+
if (node_fs_1.default.existsSync(gitignorePath)) {
|
|
144
|
+
content = node_fs_1.default.readFileSync(gitignorePath, 'utf-8');
|
|
145
|
+
const lines = content.split(/\r?\n/);
|
|
146
|
+
if (lines.some(line => line.trim() === pattern || line.trim() === '*.local/')) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const prefix = content === '' || content.endsWith('\n') ? '' : '\n';
|
|
151
|
+
node_fs_1.default.writeFileSync(gitignorePath, `${content}${prefix}${pattern}\n`, 'utf-8');
|
|
152
|
+
}
|
|
153
|
+
function parseEnvValue(content, key) {
|
|
154
|
+
const lines = content.split(/\r?\n/);
|
|
155
|
+
for (const line of lines) {
|
|
156
|
+
const trimmed = line.trim();
|
|
157
|
+
if (trimmed.startsWith('#') || !trimmed.includes('=')) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const eqIndex = trimmed.indexOf('=');
|
|
161
|
+
const k = trimmed.slice(0, eqIndex).trim();
|
|
162
|
+
let v = trimmed.slice(eqIndex + 1).trim();
|
|
163
|
+
// Remove surrounding quotes if present
|
|
164
|
+
if ((v.startsWith('"') && v.endsWith('"')) || (v.startsWith('\'') && v.endsWith('\''))) {
|
|
165
|
+
v = v.slice(1, -1);
|
|
166
|
+
}
|
|
167
|
+
if (k === key) {
|
|
168
|
+
return v;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return undefined;
|
|
172
|
+
}
|
|
173
|
+
exports.default = aiDoc;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.apifox = apifox;
|
|
4
|
+
const constant_1 = require("../../constant");
|
|
5
|
+
function apifox({ projectId, locale = 'zh-CN', apifoxVersion = '2024-03-28', scopeType = 'ALL', selectedEndpointIds = [], selectedTags = [], selectedFolderIds = [], excludedByTags = [], apifoxToken, oasVersion = '3.0', exportFormat = 'JSON', includeApifoxExtensionProperties = false, addFoldersToTags = false, environmentIds, branchId, moduleId, }) {
|
|
6
|
+
const body = {
|
|
7
|
+
scope: {
|
|
8
|
+
type: scopeType,
|
|
9
|
+
excludedByTags,
|
|
10
|
+
},
|
|
11
|
+
options: {
|
|
12
|
+
includeApifoxExtensionProperties,
|
|
13
|
+
addFoldersToTags,
|
|
14
|
+
},
|
|
15
|
+
oasVersion,
|
|
16
|
+
exportFormat,
|
|
17
|
+
environmentIds,
|
|
18
|
+
branchId,
|
|
19
|
+
moduleId,
|
|
20
|
+
};
|
|
21
|
+
// 根据不同的 scope 类型设置相应的参数
|
|
22
|
+
switch (scopeType) {
|
|
23
|
+
case 'ALL':
|
|
24
|
+
// 导出全部不需要额外参数
|
|
25
|
+
break;
|
|
26
|
+
case 'SELECTED_ENDPOINTS':
|
|
27
|
+
body.scope.selectedEndpointIds = selectedEndpointIds;
|
|
28
|
+
break;
|
|
29
|
+
case 'SELECTED_TAGS':
|
|
30
|
+
body.scope.selectedTags = selectedTags;
|
|
31
|
+
break;
|
|
32
|
+
case 'SELECTED_FOLDERS':
|
|
33
|
+
body.scope.selectedFolderIds = selectedFolderIds;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
name: constant_1.PluginName.APIFOX,
|
|
38
|
+
config({ config }) {
|
|
39
|
+
const base = 'https://api.apifox.com/v1/projects';
|
|
40
|
+
if (projectId && apifoxToken) {
|
|
41
|
+
config.input = `${base}/${encodeURIComponent(projectId)}/export-openapi?locale=${encodeURIComponent(locale)}`;
|
|
42
|
+
config.fetchOptions = {
|
|
43
|
+
...config.fetchOptions,
|
|
44
|
+
headers: {
|
|
45
|
+
'X-Apifox-Api-Version': apifoxVersion,
|
|
46
|
+
'Authorization': `Bearer ${apifoxToken}`,
|
|
47
|
+
},
|
|
48
|
+
method: 'POST',
|
|
49
|
+
data: body,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return config;
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
exports.default = apifox;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.filterApiDescriptor = filterApiDescriptor;
|
|
4
|
+
exports.apiFilter = apiFilter;
|
|
5
|
+
const constant_1 = require("../../constant");
|
|
6
|
+
const logger_1 = require("../../helper/logger");
|
|
7
|
+
const utils_1 = require("./utils");
|
|
8
|
+
/**
|
|
9
|
+
* Tests if value matches the specified rule
|
|
10
|
+
*/
|
|
11
|
+
function isMatch(value, match) {
|
|
12
|
+
if (!match)
|
|
13
|
+
return true;
|
|
14
|
+
if (typeof match === 'string') {
|
|
15
|
+
return value.includes(match);
|
|
16
|
+
}
|
|
17
|
+
if (match instanceof RegExp) {
|
|
18
|
+
return match.test(value);
|
|
19
|
+
}
|
|
20
|
+
if (typeof match === 'function') {
|
|
21
|
+
try {
|
|
22
|
+
return match(value);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return false; // Return false on error to exclude the item
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Extracts the corresponding property value from API descriptor based on scope
|
|
32
|
+
*/
|
|
33
|
+
function getApiProperty(apiDescriptor, scope) {
|
|
34
|
+
switch (scope) {
|
|
35
|
+
case constant_1.FilterScope.URL:
|
|
36
|
+
return apiDescriptor.url || '';
|
|
37
|
+
case constant_1.FilterScope.TAG:
|
|
38
|
+
// Assume tags exist in tags array, join with comma if multiple tags
|
|
39
|
+
return Array.isArray(apiDescriptor.tags) ? apiDescriptor.tags.join(',') : '';
|
|
40
|
+
default:
|
|
41
|
+
return '';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Applies filtering rules for a single configuration
|
|
46
|
+
* @param apiDescriptor API descriptor
|
|
47
|
+
* @param config Filter configuration
|
|
48
|
+
* @returns Whether it passes the filter (true means keep, false means filter out)
|
|
49
|
+
*/
|
|
50
|
+
function applyFilterRule(apiDescriptor, config) {
|
|
51
|
+
const scope = config.scope || constant_1.FilterScope.URL;
|
|
52
|
+
const value = getApiProperty(apiDescriptor, scope);
|
|
53
|
+
// Handle include and exclude logic
|
|
54
|
+
const includeMatch = config.include ? isMatch(value, config.include) : true;
|
|
55
|
+
const excludeMatch = config.exclude ? isMatch(value, config.exclude) : false;
|
|
56
|
+
// If both include and exclude are specified, exclude matching items from include
|
|
57
|
+
return includeMatch && !excludeMatch;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Handles union logic for multiple configurations
|
|
61
|
+
* @param apiDescriptor API descriptor
|
|
62
|
+
* @param configs Configuration array
|
|
63
|
+
* @returns Whether it passes the filter (true means keep, false means filter out)
|
|
64
|
+
*/
|
|
65
|
+
function combineFilterResults(apiDescriptor, configs) {
|
|
66
|
+
// If any configuration matches, keep the API (union logic)
|
|
67
|
+
return configs.some(config => applyFilterRule(apiDescriptor, config));
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Main processing function for filtering API descriptors
|
|
71
|
+
* @param apiDescriptor API descriptor
|
|
72
|
+
* @param configs Configuration array
|
|
73
|
+
* @returns Filtered API descriptor, or null if filtered out
|
|
74
|
+
*/
|
|
75
|
+
function filterApiDescriptor(apiDescriptor, configs) {
|
|
76
|
+
if (!apiDescriptor)
|
|
77
|
+
return null;
|
|
78
|
+
// Use union logic to determine whether to keep the API
|
|
79
|
+
const shouldKeep = combineFilterResults(apiDescriptor, configs);
|
|
80
|
+
return shouldKeep ? apiDescriptor : null;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Creates a plugin for filtering APIs
|
|
84
|
+
*
|
|
85
|
+
* @param config Filter configuration, can be a single config or array of configs
|
|
86
|
+
* @returns API plugin instance
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* // Only include URLs containing 'user'
|
|
91
|
+
* const userOnlyFilter = apiFilter({
|
|
92
|
+
* include: 'user'
|
|
93
|
+
* });
|
|
94
|
+
*
|
|
95
|
+
* // Exclude tags containing 'internal'
|
|
96
|
+
* const noInternalFilter = apiFilter({
|
|
97
|
+
* scope: 'tag',
|
|
98
|
+
* exclude: 'internal'
|
|
99
|
+
* });
|
|
100
|
+
*
|
|
101
|
+
* // Multi-condition filtering (union)
|
|
102
|
+
* const multiFilter = apiFilter([
|
|
103
|
+
* { include: 'user' },
|
|
104
|
+
* { include: 'admin' }
|
|
105
|
+
* ]);
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
function apiFilter(config) {
|
|
109
|
+
const configs = Array.isArray(config) ? config : [config];
|
|
110
|
+
// Validate configuration
|
|
111
|
+
for (const conf of configs) {
|
|
112
|
+
if (!conf.include && !conf.exclude) {
|
|
113
|
+
throw logger_1.logger.throwError('at least one of `include` or `exclude` must be specified');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
name: constant_1.PluginName.FILTER_API,
|
|
118
|
+
config({ config }) {
|
|
119
|
+
return (0, utils_1.extend)(config, {
|
|
120
|
+
handleApi: (apiDescriptor) => {
|
|
121
|
+
if (!apiDescriptor)
|
|
122
|
+
return null;
|
|
123
|
+
return filterApiDescriptor(apiDescriptor, configs);
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
exports.default = apiFilter;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.importType = importType;
|
|
4
|
+
const constant_1 = require("../../constant");
|
|
5
|
+
// Reusable helper: insert text after leading block comment(s) at file top
|
|
6
|
+
const LEADING_BLOCK_COMMENTS = /^\s*(?:\/\*[\s\S]*?\*\/\s*)+/;
|
|
7
|
+
function insertAfterLeadingBlockComments(content, insertion) {
|
|
8
|
+
const match = content.match(LEADING_BLOCK_COMMENTS);
|
|
9
|
+
const insertAt = match ? match[0].length : 0;
|
|
10
|
+
if (insertAt === 0) {
|
|
11
|
+
return `${insertion}\n${content}`;
|
|
12
|
+
}
|
|
13
|
+
const prefix = content.slice(0, insertAt);
|
|
14
|
+
const suffix = content.slice(insertAt);
|
|
15
|
+
const safePrefix = prefix.endsWith('\n') ? prefix : `${prefix}\n`;
|
|
16
|
+
return `${safePrefix}${insertion}\n${suffix}`;
|
|
17
|
+
}
|
|
18
|
+
function importType(imports, options) {
|
|
19
|
+
const entries = Object.entries(imports);
|
|
20
|
+
const excludedTypeNames = Array.from(new Set(entries.flatMap(([, names]) => names)));
|
|
21
|
+
const targetFiles = options?.files ?? ['globals.d'];
|
|
22
|
+
const importLines = entries
|
|
23
|
+
.map(([key, names]) => {
|
|
24
|
+
const [specifier, ...flags] = key.split('|');
|
|
25
|
+
const isTypeImport = flags.includes('type');
|
|
26
|
+
const kw = isTypeImport ? 'import type' : 'import';
|
|
27
|
+
const named = names.join(', ');
|
|
28
|
+
return `${kw} { ${named} } from '${specifier}'`;
|
|
29
|
+
})
|
|
30
|
+
.join('\n');
|
|
31
|
+
return {
|
|
32
|
+
name: constant_1.PluginName.IMPORT_TYPE,
|
|
33
|
+
config({ config: cfg }) {
|
|
34
|
+
cfg.externalTypes = Array.from(new Set([...(cfg.externalTypes ?? []), ...excludedTypeNames]));
|
|
35
|
+
return cfg;
|
|
36
|
+
},
|
|
37
|
+
// 9.1.2: Use beforeFileWrite to modify individual file content before write
|
|
38
|
+
beforeFileWrite({ filePath, content }) {
|
|
39
|
+
if (entries.length === 0)
|
|
40
|
+
return content;
|
|
41
|
+
const matched = targetFiles.some(target => filePath.includes(target));
|
|
42
|
+
if (matched) {
|
|
43
|
+
return insertAfterLeadingBlockComments(content, importLines);
|
|
44
|
+
}
|
|
45
|
+
return content;
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
exports.default = importType;
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.applyModifierSchema = applyModifierSchema;
|
|
4
|
+
// Convert Schema (custom spec) -> OpenAPI SchemaObject
|
|
5
|
+
function toSchemaObject(base, s) {
|
|
6
|
+
const result = { ...base };
|
|
7
|
+
const cleanType = (schema) => {
|
|
8
|
+
delete schema.type;
|
|
9
|
+
delete schema.enum;
|
|
10
|
+
delete schema.oneOf;
|
|
11
|
+
delete schema.anyOf;
|
|
12
|
+
delete schema.allOf;
|
|
13
|
+
delete schema.items;
|
|
14
|
+
delete schema.properties;
|
|
15
|
+
delete schema.required;
|
|
16
|
+
return schema;
|
|
17
|
+
};
|
|
18
|
+
// Legacy union as array (treated as oneOf)
|
|
19
|
+
if (Array.isArray(s)) {
|
|
20
|
+
const baseOneOf = base.oneOf || [];
|
|
21
|
+
cleanType(result);
|
|
22
|
+
result.oneOf = s.map((item, idx) => toSchemaObject(baseOneOf[idx] || {}, item));
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
// Primitive types and no-op primitives
|
|
26
|
+
if (typeof s === 'string') {
|
|
27
|
+
result.type = s;
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
// Handle union keywords: overwrite arrays but preserve unrelated fields
|
|
31
|
+
if (s.oneOf) {
|
|
32
|
+
const spec = s;
|
|
33
|
+
const baseOneOf = base.oneOf || [];
|
|
34
|
+
cleanType(result);
|
|
35
|
+
result.oneOf = spec.oneOf.map((item, idx) => toSchemaObject(baseOneOf[idx] || {}, item));
|
|
36
|
+
}
|
|
37
|
+
if (s.anyOf) {
|
|
38
|
+
const spec = s;
|
|
39
|
+
const baseAnyOf = base.anyOf || [];
|
|
40
|
+
cleanType(result);
|
|
41
|
+
result.anyOf = spec.anyOf.map((item, idx) => toSchemaObject(baseAnyOf[idx] || {}, item));
|
|
42
|
+
}
|
|
43
|
+
if (s.allOf) {
|
|
44
|
+
const spec = s;
|
|
45
|
+
const baseAllOf = base.allOf || [];
|
|
46
|
+
cleanType(result);
|
|
47
|
+
result.allOf = spec.allOf.map((item, idx) => toSchemaObject(baseAllOf[idx] || {}, item));
|
|
48
|
+
}
|
|
49
|
+
// Enum: set enum and optional type
|
|
50
|
+
if (s.enum) {
|
|
51
|
+
const spec = s;
|
|
52
|
+
result.enum = spec.enum;
|
|
53
|
+
if (spec.type) {
|
|
54
|
+
result.type = spec.type;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Array: set/merge items
|
|
58
|
+
if (s.type === 'array') {
|
|
59
|
+
const spec = s;
|
|
60
|
+
result.type = 'array';
|
|
61
|
+
const baseItems = result.items;
|
|
62
|
+
if (Array.isArray(spec.items)) {
|
|
63
|
+
// Tuple items: replace entire items with tuple
|
|
64
|
+
const items = spec.items.map(item => toSchemaObject({}, item));
|
|
65
|
+
result.items = items;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
// Single items: merge into existing items schema
|
|
69
|
+
const patchItem = toSchemaObject(typeof baseItems === 'object' ? baseItems : {}, spec.items);
|
|
70
|
+
result.items = patchItem;
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
// Object (reference-like map): merge properties and required
|
|
75
|
+
const ref = s;
|
|
76
|
+
if (ref && typeof ref === 'object') {
|
|
77
|
+
result.type = 'object';
|
|
78
|
+
const properties = { ...result.properties };
|
|
79
|
+
const requiredSet = new Set(Array.isArray(result.required) ? result.required : []);
|
|
80
|
+
for (const key in ref) {
|
|
81
|
+
const val = ref[key];
|
|
82
|
+
if (!val) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const optional = key.endsWith('?');
|
|
86
|
+
const cleanKey = optional ? key.slice(0, -1) : key;
|
|
87
|
+
const baseProp = properties[cleanKey];
|
|
88
|
+
properties[cleanKey] = toSchemaObject(baseProp || {}, val);
|
|
89
|
+
if (optional) {
|
|
90
|
+
requiredSet.delete(cleanKey);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
requiredSet.add(cleanKey);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
result.properties = properties;
|
|
97
|
+
result.required = Array.from(requiredSet);
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
function schemaTypeToPrimitiveType(t) {
|
|
103
|
+
if (t === null) {
|
|
104
|
+
return 'null';
|
|
105
|
+
}
|
|
106
|
+
if (t === undefined) {
|
|
107
|
+
return 'undefined';
|
|
108
|
+
}
|
|
109
|
+
if (!t) {
|
|
110
|
+
return 'unknown';
|
|
111
|
+
}
|
|
112
|
+
if (t === 'integer') {
|
|
113
|
+
return 'number';
|
|
114
|
+
}
|
|
115
|
+
return t;
|
|
116
|
+
}
|
|
117
|
+
// Convert existing OpenAPI SchemaObject -> Schema (best-effort, for handler input)
|
|
118
|
+
function toSchemaSpec(obj) {
|
|
119
|
+
if (!obj || typeof obj !== 'object') {
|
|
120
|
+
return 'unknown';
|
|
121
|
+
}
|
|
122
|
+
// Union keywords
|
|
123
|
+
if (Array.isArray(obj.oneOf)) {
|
|
124
|
+
const arr = obj.oneOf;
|
|
125
|
+
return { oneOf: arr.map(item => toSchemaSpec(item)) };
|
|
126
|
+
}
|
|
127
|
+
if (Array.isArray(obj.anyOf)) {
|
|
128
|
+
const arr = obj.anyOf;
|
|
129
|
+
return { anyOf: arr.map(item => toSchemaSpec(item)) };
|
|
130
|
+
}
|
|
131
|
+
if (Array.isArray(obj.allOf)) {
|
|
132
|
+
const arr = obj.allOf;
|
|
133
|
+
return { allOf: arr.map(item => toSchemaSpec(item)) };
|
|
134
|
+
}
|
|
135
|
+
// Enum
|
|
136
|
+
if (Array.isArray(obj.enum) && obj.enum.length > 0) {
|
|
137
|
+
const type = typeof obj.type === 'string' ? obj.type : undefined;
|
|
138
|
+
return { enum: obj.enum, type };
|
|
139
|
+
}
|
|
140
|
+
// Array
|
|
141
|
+
if (obj.type === 'array' || obj.items) {
|
|
142
|
+
const items = obj.items;
|
|
143
|
+
if (Array.isArray(items)) {
|
|
144
|
+
return { type: 'array', items: items.map((it) => toSchemaSpec(it)) };
|
|
145
|
+
}
|
|
146
|
+
if (items) {
|
|
147
|
+
return { type: 'array', items: toSchemaSpec(items) };
|
|
148
|
+
}
|
|
149
|
+
return { type: 'array', items: 'unknown' };
|
|
150
|
+
}
|
|
151
|
+
// Object
|
|
152
|
+
if (obj.type === 'object' || obj.properties) {
|
|
153
|
+
const properties = obj.properties || {};
|
|
154
|
+
const requiredSet = new Set(Array.isArray(obj.required) ? obj.required : []);
|
|
155
|
+
const result = {};
|
|
156
|
+
for (const key of Object.keys(properties)) {
|
|
157
|
+
const spec = toSchemaSpec(properties[key]);
|
|
158
|
+
const finalKey = requiredSet.has(key) ? key : `${key}?`;
|
|
159
|
+
result[finalKey] = spec;
|
|
160
|
+
}
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
// type union as array
|
|
164
|
+
if (Array.isArray(obj.type)) {
|
|
165
|
+
const typeArr = obj.type;
|
|
166
|
+
const mapped = typeArr.map(schemaTypeToPrimitiveType);
|
|
167
|
+
return { oneOf: mapped };
|
|
168
|
+
}
|
|
169
|
+
return schemaTypeToPrimitiveType(obj.type);
|
|
170
|
+
}
|
|
171
|
+
// Replace whole schema based on handler result (used for params/pathParams)
|
|
172
|
+
function applyModifierSchema(schema, config, { required }) {
|
|
173
|
+
if (!schema || typeof schema !== 'object') {
|
|
174
|
+
return schema;
|
|
175
|
+
}
|
|
176
|
+
const cloned = { ...schema };
|
|
177
|
+
const currentSpec = toSchemaSpec(cloned);
|
|
178
|
+
const ret = config.handler(currentSpec);
|
|
179
|
+
if (!ret) {
|
|
180
|
+
return {
|
|
181
|
+
required,
|
|
182
|
+
value: null,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
if (typeof ret === 'object' && 'required' in ret && 'value' in ret) {
|
|
186
|
+
return {
|
|
187
|
+
required: !!(ret.required ?? required),
|
|
188
|
+
value: toSchemaObject(cloned, ret.value),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
required,
|
|
193
|
+
value: toSchemaObject(cloned, ret),
|
|
194
|
+
};
|
|
195
|
+
}
|