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,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PoolManager = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* P2: Global reusable WorkerPool manager (singleton factory).
|
|
6
|
+
* Caches pools by key to avoid create/destroy overhead across repeated generate() calls.
|
|
7
|
+
* Workers auto-terminate after idleTimeout (default 30s) of inactivity.
|
|
8
|
+
*/
|
|
9
|
+
const WorkerPool_1 = require("../../core/WorkerPool");
|
|
10
|
+
class PoolManager {
|
|
11
|
+
static getInstance() {
|
|
12
|
+
if (!PoolManager.instance) {
|
|
13
|
+
PoolManager.instance = new PoolManager();
|
|
14
|
+
}
|
|
15
|
+
return PoolManager.instance;
|
|
16
|
+
}
|
|
17
|
+
constructor() {
|
|
18
|
+
this.pools = new Map();
|
|
19
|
+
}
|
|
20
|
+
get(options) {
|
|
21
|
+
const { key, workerScript, sharedContext, poolSize, idleTimeout } = options;
|
|
22
|
+
let pool = this.pools.get(key);
|
|
23
|
+
if (!pool) {
|
|
24
|
+
pool = new WorkerPool_1.WorkerPool({ workerScript, sharedContext, poolSize, idleTimeout });
|
|
25
|
+
this.pools.set(key, pool);
|
|
26
|
+
}
|
|
27
|
+
return pool;
|
|
28
|
+
}
|
|
29
|
+
/** Explicitly terminate and remove a pool (e.g. on project config change). */
|
|
30
|
+
release(key) {
|
|
31
|
+
const pool = this.pools.get(key);
|
|
32
|
+
if (pool) {
|
|
33
|
+
pool.terminate();
|
|
34
|
+
this.pools.delete(key);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** Terminate all cached pools. */
|
|
38
|
+
releaseAll() {
|
|
39
|
+
for (const [, pool] of this.pools) {
|
|
40
|
+
pool.terminate();
|
|
41
|
+
}
|
|
42
|
+
this.pools.clear();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.PoolManager = PoolManager;
|
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
/**
|
|
7
|
+
* 9.3.4: Worker for Swagger2→OpenAPI3 conversion (moved from openApiParser).
|
|
8
|
+
* Handles batches of swagger2 documents via WorkerPool.
|
|
9
|
+
*/
|
|
10
|
+
const node_worker_threads_1 = require("node:worker_threads");
|
|
11
|
+
const swagger2openapi_1 = __importDefault(require("swagger2openapi"));
|
|
12
|
+
node_worker_threads_1.parentPort?.on('message', async (batch) => {
|
|
13
|
+
const results = [];
|
|
14
|
+
try {
|
|
15
|
+
for (const data of batch) {
|
|
16
|
+
const result = await swagger2openapi_1.default.convertObj(data, { warnOnly: true });
|
|
17
|
+
results.push({ openapi: result.openapi });
|
|
18
|
+
}
|
|
19
|
+
node_worker_threads_1.parentPort?.postMessage({ type: 'result', data: results });
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
node_worker_threads_1.parentPort?.postMessage({ type: 'error', message: err.message });
|
|
23
|
+
}
|
|
24
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* M4-C1: Worker entry point for schema→TS conversion.
|
|
5
|
+
* Each worker receives shared context (document + config) at startup,
|
|
6
|
+
* then processes batches of schema objects in its own thread.
|
|
7
|
+
*/
|
|
8
|
+
const node_worker_threads_1 = require("node:worker_threads");
|
|
9
|
+
// Initialize global config required by logger etc.
|
|
10
|
+
const config_1 = require("../../config");
|
|
11
|
+
const loader_1 = require("../../core/loader");
|
|
12
|
+
(0, config_1.setGlobalConfig)({ Error });
|
|
13
|
+
const { document, config, refNameMapEntries } = node_worker_threads_1.workerData;
|
|
14
|
+
const refNameMap = new Map(refNameMapEntries);
|
|
15
|
+
/** Worker-local cache: keyName → generated TS string, avoids re-transforming the same referenced schema. */
|
|
16
|
+
const schemaCache = new Map();
|
|
17
|
+
async function processSchema(key, schema) {
|
|
18
|
+
const results = [];
|
|
19
|
+
const tsStr = await loader_1.schemaLoader.transform(schema, {
|
|
20
|
+
document,
|
|
21
|
+
deep: false,
|
|
22
|
+
noEnum: true,
|
|
23
|
+
commentType: 'doc',
|
|
24
|
+
preText: '',
|
|
25
|
+
defaultRequire: config.defaultRequire,
|
|
26
|
+
refNameMap,
|
|
27
|
+
async onReference(ast) {
|
|
28
|
+
if (config.externalTypes?.includes(ast.keyName ?? ''))
|
|
29
|
+
return;
|
|
30
|
+
if (ast.keyName) {
|
|
31
|
+
let result = schemaCache.get(ast.keyName);
|
|
32
|
+
if (!result) {
|
|
33
|
+
result = await loader_1.astLoader.transformTsStr(ast, {
|
|
34
|
+
shallowDeep: true,
|
|
35
|
+
commentType: 'doc',
|
|
36
|
+
noEnum: true,
|
|
37
|
+
format: true,
|
|
38
|
+
export: true,
|
|
39
|
+
});
|
|
40
|
+
schemaCache.set(ast.keyName, result);
|
|
41
|
+
}
|
|
42
|
+
results.push({ key: ast.keyName, result });
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
results.push({ key, result: tsStr });
|
|
47
|
+
return results;
|
|
48
|
+
}
|
|
49
|
+
node_worker_threads_1.parentPort?.on('message', async (batch) => {
|
|
50
|
+
try {
|
|
51
|
+
const allResults = [];
|
|
52
|
+
for (const item of batch) {
|
|
53
|
+
const taskResults = await processSchema(item.key, item.schema);
|
|
54
|
+
allResults.push(...taskResults);
|
|
55
|
+
}
|
|
56
|
+
node_worker_threads_1.parentPort?.postMessage({ type: 'result', data: allResults });
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
node_worker_threads_1.parentPort?.postMessage({ type: 'error', message: err.message });
|
|
60
|
+
}
|
|
61
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
7
|
+
const constant_1 = require("./constant");
|
|
8
|
+
const getAutoTemplateType_1 = __importDefault(require("./functions/getAutoTemplateType"));
|
|
9
|
+
const helper_1 = require("./helper");
|
|
10
|
+
const template_1 = require("./template");
|
|
11
|
+
const TEMPLATE_PRESET_MAP = {
|
|
12
|
+
alovaGlobals: { importName: 'alovaGlobals', call: 'alovaGlobals()', presetName: constant_1.PresetTemplateName.GLOBALS },
|
|
13
|
+
[constant_1.PresetTemplateName.ALOVA]: { importName: 'alova', call: 'alova()', presetName: constant_1.PresetTemplateName.ALOVA },
|
|
14
|
+
[constant_1.PresetTemplateName.AXIOS]: { importName: 'axios', call: 'axios()', presetName: constant_1.PresetTemplateName.AXIOS },
|
|
15
|
+
[constant_1.PresetTemplateName.FETCH]: { importName: 'fetch', call: 'fetch()', presetName: constant_1.PresetTemplateName.FETCH },
|
|
16
|
+
[constant_1.PresetTemplateName.KY]: { importName: 'ky', call: 'ky()', presetName: constant_1.PresetTemplateName.KY },
|
|
17
|
+
};
|
|
18
|
+
async function createConfig({ projectPath = '', type, template = constant_1.PresetTemplateName.ALOVA } = {}) {
|
|
19
|
+
projectPath = node_path_1.default.isAbsolute(projectPath)
|
|
20
|
+
? projectPath
|
|
21
|
+
: node_path_1.default.resolve(process.cwd(), projectPath);
|
|
22
|
+
type = type || await (0, getAutoTemplateType_1.default)(projectPath);
|
|
23
|
+
const preset = TEMPLATE_PRESET_MAP[template];
|
|
24
|
+
const templatePath = (0, template_1.getPresetTemplatePath)(constant_1.PresetTemplateName.CONFIG);
|
|
25
|
+
helper_1.templateHelper.load({
|
|
26
|
+
type,
|
|
27
|
+
templatePath,
|
|
28
|
+
});
|
|
29
|
+
// generateFromTemplateDir now writes files internally
|
|
30
|
+
await helper_1.templateHelper.generateFromTemplateDir(templatePath, projectPath, {
|
|
31
|
+
type,
|
|
32
|
+
moduleType: helper_1.templateHelper.getModuleType(),
|
|
33
|
+
templateImport: preset.importName,
|
|
34
|
+
templateCall: preset.call,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
exports.default = createConfig;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = getAutoTemplateType;
|
|
4
|
+
exports.getFrameworkTag = getFrameworkTag;
|
|
5
|
+
const constant_1 = require("../constant");
|
|
6
|
+
const readPackageJson_1 = require("../utils/readPackageJson");
|
|
7
|
+
/**
|
|
8
|
+
* Get the template type based on project configuration
|
|
9
|
+
* @param projectPath - The project root path
|
|
10
|
+
* @returns TemplateType - 'typescript' | 'module' | 'commonjs'
|
|
11
|
+
*/
|
|
12
|
+
async function getAutoTemplateType(projectPath) {
|
|
13
|
+
const packageJson = await (0, readPackageJson_1.readPackageJson)(projectPath);
|
|
14
|
+
if (packageJson?.devDependencies?.typescript) {
|
|
15
|
+
return constant_1.TemplateTypeEnum.TYPESCRIPT;
|
|
16
|
+
}
|
|
17
|
+
const type = packageJson?.type;
|
|
18
|
+
return type ?? constant_1.TemplateTypeEnum.MODULE;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get the framework tag based on project dependencies
|
|
22
|
+
* @param projectPath - The project root path
|
|
23
|
+
* @returns FrameworkName or empty string
|
|
24
|
+
*/
|
|
25
|
+
async function getFrameworkTag(projectPath) {
|
|
26
|
+
const packageJson = await (0, readPackageJson_1.readPackageJson)(projectPath);
|
|
27
|
+
if (!packageJson) {
|
|
28
|
+
return '';
|
|
29
|
+
}
|
|
30
|
+
// Framework technology stack tag vue | react
|
|
31
|
+
// Find in dependencies
|
|
32
|
+
const frameTag = constant_1.FRAMEWORK_NAMES.find(framework => packageJson.dependencies?.[framework]);
|
|
33
|
+
// Find in dev dependencies
|
|
34
|
+
// Priority: Production dependencies > Development dependencies
|
|
35
|
+
const devFrameTag = constant_1.FRAMEWORK_NAMES.find(framework => packageJson.devDependencies?.[framework]);
|
|
36
|
+
return frameTag ?? devFrameTag ?? '';
|
|
37
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = default_1;
|
|
4
|
+
const constant_1 = require("../constant");
|
|
5
|
+
const readPackageJson_1 = require("../utils/readPackageJson");
|
|
6
|
+
async function default_1(projectPath) {
|
|
7
|
+
const packageJson = await (0, readPackageJson_1.readPackageJson)(projectPath);
|
|
8
|
+
if (!packageJson) {
|
|
9
|
+
return '';
|
|
10
|
+
}
|
|
11
|
+
// Framework technology stack tag vue | react
|
|
12
|
+
// Find in dependencies
|
|
13
|
+
const frameTag = constant_1.FRAMEWORK_NAMES.find(framework => packageJson.dependencies?.[framework]);
|
|
14
|
+
// Find in dev dependencies
|
|
15
|
+
// Priority: Production dependencies > Development dependencies
|
|
16
|
+
const devFrameTag = constant_1.FRAMEWORK_NAMES.find(framework => packageJson.devDependencies?.[framework]);
|
|
17
|
+
return frameTag ?? devFrameTag ?? '';
|
|
18
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extendsConfig = extendsConfig;
|
|
4
|
+
exports.prepareConfig = prepareConfig;
|
|
5
|
+
const lodash_1 = require("lodash");
|
|
6
|
+
const helper_1 = require("../helper");
|
|
7
|
+
function extendsConfig(config, newConfig) {
|
|
8
|
+
const mergedConfig = (0, lodash_1.cloneDeep)(config);
|
|
9
|
+
return (0, lodash_1.mergeWith)(mergedConfig, newConfig, (srcValue, newValue, key) => {
|
|
10
|
+
if (key !== 'handleApi') {
|
|
11
|
+
return newValue ?? srcValue; // fallback to default merge behavior
|
|
12
|
+
}
|
|
13
|
+
// handleApi is a special case, we need to merge the functions
|
|
14
|
+
if (typeof newValue === 'function' && typeof srcValue === 'function') {
|
|
15
|
+
// chain the functions
|
|
16
|
+
return (...args) => {
|
|
17
|
+
const result = srcValue(...args);
|
|
18
|
+
// null or undefined return is a valid value for filtering
|
|
19
|
+
// if plugin return undefined or null, we should break the chain
|
|
20
|
+
if (!result) {
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
return newValue(result);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return newValue ?? srcValue; // fallback to default merge behavior
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async function prepareConfig(config, projectPath = process.cwd(), tracker) {
|
|
30
|
+
let _config = (0, lodash_1.cloneDeep)(config);
|
|
31
|
+
const plugins = _config.plugins || [];
|
|
32
|
+
const reporter = (plugin) => tracker?.reporterFor(plugin.name ?? 'plugin') ?? (() => { });
|
|
33
|
+
const pluginDriver = new helper_1.PluginDriver(plugins, { reporter });
|
|
34
|
+
// plugin: handle config hook
|
|
35
|
+
_config = await pluginDriver.hookSeqEach('config', (_plugin, prevResult, _ctx) => {
|
|
36
|
+
const nextConfig = prevResult ?? _config;
|
|
37
|
+
return { config: nextConfig, projectPath };
|
|
38
|
+
}) ?? _config;
|
|
39
|
+
return _config;
|
|
40
|
+
}
|
|
41
|
+
exports.default = prepareConfig;
|
|
@@ -0,0 +1,155 @@
|
|
|
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.readWormaRc = readWormaRc;
|
|
7
|
+
exports.hasWormaRc = hasWormaRc;
|
|
8
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const constant_1 = require("../constant");
|
|
11
|
+
const logger_1 = require("../helper/logger");
|
|
12
|
+
const plugins_1 = require("../plugins");
|
|
13
|
+
const template_1 = require("../template");
|
|
14
|
+
/**
|
|
15
|
+
* Parse a single line from .wormarc file
|
|
16
|
+
*
|
|
17
|
+
* Supported formats:
|
|
18
|
+
* - `https://xxxx.com/openapi.json` -> generates in src/api, default alova template
|
|
19
|
+
* - `https://yyyy.com/openapi.json, axios` -> generates in src/api2, axios template
|
|
20
|
+
* - `myApi=https://zzzz.com/openapi.json` -> generates in src/myApi, default alova template
|
|
21
|
+
* - `myApi=https://zzzz.com/openapi.json, fetch` -> generates in src/myApi, fetch template
|
|
22
|
+
*/
|
|
23
|
+
function parseLine(line) {
|
|
24
|
+
line = line.trim();
|
|
25
|
+
if (!line) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
// Lines starting with # are full-line comments
|
|
29
|
+
if (line.startsWith('#')) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
// Strip inline comments: ` //` (space before //) to avoid matching // in URLs
|
|
33
|
+
const inlineCommentIndex = line.indexOf(' //');
|
|
34
|
+
if (inlineCommentIndex !== -1) {
|
|
35
|
+
line = line.substring(0, inlineCommentIndex).trim();
|
|
36
|
+
}
|
|
37
|
+
if (!line) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
let outputKey;
|
|
41
|
+
let url;
|
|
42
|
+
let template;
|
|
43
|
+
// Check for key=value format
|
|
44
|
+
const equalIndex = line.indexOf('=');
|
|
45
|
+
if (equalIndex !== -1) {
|
|
46
|
+
outputKey = line.substring(0, equalIndex).trim();
|
|
47
|
+
line = line.substring(equalIndex + 1).trim();
|
|
48
|
+
}
|
|
49
|
+
// Split by comma to get URL and template
|
|
50
|
+
const commaIndex = line.indexOf(',');
|
|
51
|
+
if (commaIndex !== -1) {
|
|
52
|
+
url = line.substring(0, commaIndex).trim();
|
|
53
|
+
template = line.substring(commaIndex + 1).trim() || undefined;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
url = line.trim();
|
|
57
|
+
}
|
|
58
|
+
if (!url) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
outputKey,
|
|
63
|
+
url,
|
|
64
|
+
template: template,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Template type mapping to plugin factories
|
|
69
|
+
*/
|
|
70
|
+
const PRESET_TEMPLATES = {
|
|
71
|
+
alova: template_1.alova,
|
|
72
|
+
alovaGlobals: template_1.alovaGlobals,
|
|
73
|
+
axios: template_1.axios,
|
|
74
|
+
fetch: template_1.fetch,
|
|
75
|
+
ky: template_1.ky,
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Read and parse .wormarc file
|
|
79
|
+
*
|
|
80
|
+
* File format:
|
|
81
|
+
* ```bash
|
|
82
|
+
* # Comment lines start with #
|
|
83
|
+
* https://xxxx.com/openapi.json
|
|
84
|
+
* https://yyyy.com/openapi.json, axios
|
|
85
|
+
* myApi=https://zzzz.com/openapi.json, fetch
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* @param projectPath The project path where .wormarc file is located
|
|
89
|
+
* @returns Parsed configuration or null if file doesn't exist
|
|
90
|
+
*/
|
|
91
|
+
async function readWormaRc(projectPath) {
|
|
92
|
+
const rcPath = node_path_1.default.join(projectPath, '.wormarc');
|
|
93
|
+
try {
|
|
94
|
+
const content = await promises_1.default.readFile(rcPath, 'utf-8');
|
|
95
|
+
const lines = content.split('\n');
|
|
96
|
+
const generators = [];
|
|
97
|
+
let defaultIndex = 1;
|
|
98
|
+
for (const line of lines) {
|
|
99
|
+
const parsed = parseLine(line);
|
|
100
|
+
if (!parsed) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
const { outputKey, url, template = constant_1.PresetTemplateName.ALOVA } = parsed;
|
|
104
|
+
// Determine output folder
|
|
105
|
+
let output;
|
|
106
|
+
if (outputKey) {
|
|
107
|
+
// If outputKey contains `/`, use it as-is (already a path)
|
|
108
|
+
output = outputKey.includes('/') ? outputKey : `src/${outputKey}`;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
// Default folder is src/api, src/api2, etc.
|
|
112
|
+
output = defaultIndex === 1 ? 'src/api' : `src/api${defaultIndex}`;
|
|
113
|
+
defaultIndex++;
|
|
114
|
+
}
|
|
115
|
+
// Set template if specified
|
|
116
|
+
if (!template || !PRESET_TEMPLATES[template]) {
|
|
117
|
+
throw logger_1.logger.throwError(`Invalid template: ${template}. Available templates: ${Object.keys(PRESET_TEMPLATES).join(', ')}`);
|
|
118
|
+
}
|
|
119
|
+
// Build generator config
|
|
120
|
+
const generatorConfig = {
|
|
121
|
+
input: url,
|
|
122
|
+
output,
|
|
123
|
+
plugins: [PRESET_TEMPLATES[template](), (0, plugins_1.aiDoc)({ installSkill: true })],
|
|
124
|
+
};
|
|
125
|
+
generators.push(generatorConfig);
|
|
126
|
+
}
|
|
127
|
+
if (generators.length === 0) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
generator: generators,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
// File doesn't exist or can't be read
|
|
136
|
+
if (error.code === 'ENOENT') {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
logger_1.logger.warn('Failed to read .wormarc file:', error);
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Check if .wormarc file exists
|
|
145
|
+
*/
|
|
146
|
+
async function hasWormaRc(projectPath) {
|
|
147
|
+
const rcPath = node_path_1.default.join(projectPath, '.wormarc');
|
|
148
|
+
try {
|
|
149
|
+
await promises_1.default.access(rcPath);
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
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.toCacheRelativePath = toCacheRelativePath;
|
|
7
|
+
exports.computeApiHash = computeApiHash;
|
|
8
|
+
exports.computePerTagHashes = computePerTagHashes;
|
|
9
|
+
exports.readCacheIndex = readCacheIndex;
|
|
10
|
+
exports.writeApiCacheEntry = writeApiCacheEntry;
|
|
11
|
+
exports.writeCacheIndex = writeCacheIndex;
|
|
12
|
+
exports.writeCacheEntry = writeCacheEntry;
|
|
13
|
+
exports.readCacheApis = readCacheApis;
|
|
14
|
+
exports.readAllCacheApis = readAllCacheApis;
|
|
15
|
+
exports.getCacheEntry = getCacheEntry;
|
|
16
|
+
exports.diffChangedTags = diffChangedTags;
|
|
17
|
+
exports.toCacheData = toCacheData;
|
|
18
|
+
const node_crypto_1 = require("node:crypto");
|
|
19
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
20
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
21
|
+
const config_1 = require("../config");
|
|
22
|
+
// ---- Directory-based cache format ----
|
|
23
|
+
const CACHE_SCHEMA_VERSION = 1;
|
|
24
|
+
function slugify(p) {
|
|
25
|
+
return p.replace(/[\\/.]/g, '_').replace(/[^\w-]/g, '').slice(0, 128);
|
|
26
|
+
}
|
|
27
|
+
/** Get the effective cache root directory. When cacheRoot is set in global config, it overrides projectRoot. */
|
|
28
|
+
function getCacheRoot(projectRoot) {
|
|
29
|
+
return (0, config_1.getGlobalConfig)().cacheRoot || projectRoot;
|
|
30
|
+
}
|
|
31
|
+
function cacheDirPath(projectRoot) {
|
|
32
|
+
return node_path_1.default.join(getCacheRoot(projectRoot), (0, config_1.getGlobalConfig)().cacheDir);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Resolve outputPath to a cache-root-relative path used as the lookup key in cache index.
|
|
36
|
+
* In monorepo mode (cacheRoot ≠ projectPath), this converts a sub-package-relative path
|
|
37
|
+
* to a workspace-root-relative path so all caches live under one directory.
|
|
38
|
+
*/
|
|
39
|
+
function toCacheRelativePath(projectPath, outputPath) {
|
|
40
|
+
const cacheRoot = (0, config_1.getGlobalConfig)().cacheRoot;
|
|
41
|
+
if (!cacheRoot || cacheRoot === projectPath) {
|
|
42
|
+
return outputPath.replace(/\\/g, '/');
|
|
43
|
+
}
|
|
44
|
+
const absoluteOutput = node_path_1.default.isAbsolute(outputPath)
|
|
45
|
+
? outputPath
|
|
46
|
+
: node_path_1.default.resolve(projectPath, outputPath);
|
|
47
|
+
return (node_path_1.default.relative(cacheRoot, absoluteOutput) || '.').replace(/\\/g, '/');
|
|
48
|
+
}
|
|
49
|
+
// ---- M3-B2: API hash computation ----
|
|
50
|
+
/**
|
|
51
|
+
* P2: WeakMap cache for per-Api hashes. Same Api object reused across
|
|
52
|
+
* incremental runs shares the cached hash, avoiding redundant SHA256.
|
|
53
|
+
*/
|
|
54
|
+
const apiHashCache = new WeakMap();
|
|
55
|
+
/**
|
|
56
|
+
* Compute stable hash for a single API (only essential fields).
|
|
57
|
+
* Result is cached per Api object identity via WeakMap.
|
|
58
|
+
*/
|
|
59
|
+
function computeApiHash(api) {
|
|
60
|
+
if (apiHashCache.has(api)) {
|
|
61
|
+
return apiHashCache.get(api);
|
|
62
|
+
}
|
|
63
|
+
const { tag, method, path: apiPath, name, response, requestBody, queryParameters, pathParameters } = api;
|
|
64
|
+
const hash = (0, node_crypto_1.createHash)('sha256')
|
|
65
|
+
.update(JSON.stringify({ tag, method, path: apiPath, name, response, requestBody, queryParameters, pathParameters }))
|
|
66
|
+
.digest('hex')
|
|
67
|
+
.slice(0, 16);
|
|
68
|
+
apiHashCache.set(api, hash);
|
|
69
|
+
return hash;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Compute aggregate hash + per-tag hashes for a set of APIs.
|
|
73
|
+
* When `tagedApis` is provided, avoids re-grouping APIs by tag.
|
|
74
|
+
*/
|
|
75
|
+
function computePerTagHashes(allApis, tagedApis) {
|
|
76
|
+
const tags = {};
|
|
77
|
+
const allHashes = [];
|
|
78
|
+
if (tagedApis) {
|
|
79
|
+
// P2: Use pre-grouped tagedApis to avoid O(n) re-grouping loop
|
|
80
|
+
for (const { tagName, apis: groupApis } of tagedApis) {
|
|
81
|
+
const hashes = groupApis.map(computeApiHash).sort();
|
|
82
|
+
allHashes.push(...hashes);
|
|
83
|
+
tags[tagName] = (0, node_crypto_1.createHash)('sha256').update(hashes.join('')).digest('hex').slice(0, 16);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
const tagGroups = new Map();
|
|
88
|
+
for (const api of allApis) {
|
|
89
|
+
const group = tagGroups.get(api.tag) || [];
|
|
90
|
+
group.push(api);
|
|
91
|
+
tagGroups.set(api.tag, group);
|
|
92
|
+
}
|
|
93
|
+
for (const [tag, groupApis] of tagGroups) {
|
|
94
|
+
const hashes = groupApis.map(computeApiHash).sort();
|
|
95
|
+
allHashes.push(...hashes);
|
|
96
|
+
tags[tag] = (0, node_crypto_1.createHash)('sha256').update(hashes.join('')).digest('hex').slice(0, 16);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const aggregateHash = (0, node_crypto_1.createHash)('sha256').update(allHashes.sort().join('')).digest('hex').slice(0, 16);
|
|
100
|
+
return { hash: aggregateHash, tags };
|
|
101
|
+
}
|
|
102
|
+
// ---- M3-B3: New format read/write ----
|
|
103
|
+
async function readCacheIndex(projectRoot) {
|
|
104
|
+
try {
|
|
105
|
+
const indexFile = node_path_1.default.join(cacheDirPath(projectRoot), 'index.json');
|
|
106
|
+
const content = await promises_1.default.readFile(indexFile, 'utf-8');
|
|
107
|
+
const index = JSON.parse(content);
|
|
108
|
+
if (index.schemaVersion !== CACHE_SCHEMA_VERSION)
|
|
109
|
+
return null;
|
|
110
|
+
if (!Array.isArray(index.entries))
|
|
111
|
+
return null;
|
|
112
|
+
return index;
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/** Write a single entry's API data file to disk (without updating index). */
|
|
119
|
+
async function writeApiCacheEntry(projectRoot, outputPath, serverName, apis) {
|
|
120
|
+
const dataDir = node_path_1.default.join(cacheDirPath(projectRoot), 'data');
|
|
121
|
+
const slug = slugify(outputPath);
|
|
122
|
+
const entryFile = node_path_1.default.join(dataDir, `${slug}.json`);
|
|
123
|
+
await promises_1.default.mkdir(node_path_1.default.dirname(entryFile), { recursive: true });
|
|
124
|
+
await promises_1.default.writeFile(entryFile, JSON.stringify({ serverName, apis }));
|
|
125
|
+
}
|
|
126
|
+
/** Write/update the cache index.json from pre-computed entries. */
|
|
127
|
+
async function writeCacheIndex(projectRoot, newEntries) {
|
|
128
|
+
const dir = cacheDirPath(projectRoot);
|
|
129
|
+
let index;
|
|
130
|
+
try {
|
|
131
|
+
const indexFile = node_path_1.default.join(dir, 'index.json');
|
|
132
|
+
index = JSON.parse(await promises_1.default.readFile(indexFile, 'utf-8'));
|
|
133
|
+
if (index.schemaVersion !== CACHE_SCHEMA_VERSION)
|
|
134
|
+
index = { schemaVersion: CACHE_SCHEMA_VERSION, entries: [] };
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
index = { schemaVersion: CACHE_SCHEMA_VERSION, entries: [] };
|
|
138
|
+
}
|
|
139
|
+
for (const newEntry of newEntries) {
|
|
140
|
+
const existingIdx = index.entries.findIndex(e => e.path === newEntry.path);
|
|
141
|
+
if (existingIdx >= 0)
|
|
142
|
+
index.entries[existingIdx] = newEntry;
|
|
143
|
+
else
|
|
144
|
+
index.entries.push(newEntry);
|
|
145
|
+
}
|
|
146
|
+
index.entries.sort((a, b) => a.path.localeCompare(b.path));
|
|
147
|
+
await promises_1.default.mkdir(dir, { recursive: true });
|
|
148
|
+
await promises_1.default.writeFile(node_path_1.default.join(dir, 'index.json'), JSON.stringify(index));
|
|
149
|
+
}
|
|
150
|
+
async function writeCacheEntry(projectRoot, outputPath, serverName, apis, hashInfo) {
|
|
151
|
+
// Resolve to cache-root-relative path: in monorepo this produces e.g. "packages/a/src/api"
|
|
152
|
+
const relativePath = toCacheRelativePath(projectRoot, outputPath);
|
|
153
|
+
await writeApiCacheEntry(projectRoot, relativePath, serverName, apis);
|
|
154
|
+
await writeCacheIndex(projectRoot, [{ path: relativePath, serverName, hash: hashInfo.hash, tags: hashInfo.tags }]);
|
|
155
|
+
}
|
|
156
|
+
/** Read APIs from cache directory */
|
|
157
|
+
async function readCacheApis(projectRoot, outputPath) {
|
|
158
|
+
const relativePath = toCacheRelativePath(projectRoot, outputPath);
|
|
159
|
+
const index = await readCacheIndex(projectRoot);
|
|
160
|
+
if (index) {
|
|
161
|
+
const entry = index.entries.find(e => e.path === relativePath);
|
|
162
|
+
if (entry) {
|
|
163
|
+
const slug = slugify(relativePath);
|
|
164
|
+
const entryFile = node_path_1.default.join(cacheDirPath(projectRoot), 'data', `${slug}.json`);
|
|
165
|
+
try {
|
|
166
|
+
const content = JSON.parse(await promises_1.default.readFile(entryFile, 'utf-8'));
|
|
167
|
+
return { path: relativePath, serverName: content.serverName, apis: content.apis };
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Read ALL cached API entries from the unified cache directory.
|
|
178
|
+
* In monorepo mode where cacheRoot unifies all sub-package caches,
|
|
179
|
+
* this returns entries from every sub-project at once.
|
|
180
|
+
*/
|
|
181
|
+
async function readAllCacheApis(projectRoot) {
|
|
182
|
+
const index = await readCacheIndex(projectRoot);
|
|
183
|
+
if (!index)
|
|
184
|
+
return [];
|
|
185
|
+
const results = [];
|
|
186
|
+
const dataDir = node_path_1.default.join(cacheDirPath(projectRoot), 'data');
|
|
187
|
+
for (const entry of index.entries) {
|
|
188
|
+
const slug = slugify(entry.path);
|
|
189
|
+
const entryFile = node_path_1.default.join(dataDir, `${slug}.json`);
|
|
190
|
+
try {
|
|
191
|
+
const content = JSON.parse(await promises_1.default.readFile(entryFile, 'utf-8'));
|
|
192
|
+
results.push({
|
|
193
|
+
path: entry.path,
|
|
194
|
+
serverName: content.serverName || entry.serverName || '',
|
|
195
|
+
apis: content.apis || [],
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
catch { /* skip corrupted data file */ }
|
|
199
|
+
}
|
|
200
|
+
return results;
|
|
201
|
+
}
|
|
202
|
+
/** Get cache entry metadata (hash + tags) without loading APIs */
|
|
203
|
+
async function getCacheEntry(projectRoot, outputPath) {
|
|
204
|
+
const relativePath = toCacheRelativePath(projectRoot, outputPath);
|
|
205
|
+
const index = await readCacheIndex(projectRoot);
|
|
206
|
+
if (!index)
|
|
207
|
+
return null;
|
|
208
|
+
return index.entries.find(e => e.path === relativePath) ?? null;
|
|
209
|
+
}
|
|
210
|
+
/** Find set of tags whose hash differs between old and new */
|
|
211
|
+
function diffChangedTags(oldTags, newTags) {
|
|
212
|
+
const changed = new Set();
|
|
213
|
+
for (const [tag, tagHash] of Object.entries(newTags)) {
|
|
214
|
+
if (oldTags[tag] !== tagHash)
|
|
215
|
+
changed.add(tag);
|
|
216
|
+
}
|
|
217
|
+
for (const tag of Object.keys(oldTags)) {
|
|
218
|
+
if (!newTags[tag])
|
|
219
|
+
changed.add(tag); // removed tags
|
|
220
|
+
}
|
|
221
|
+
return changed;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Convert TemplateData to standardized CacheData entry.
|
|
225
|
+
*/
|
|
226
|
+
function toCacheData(templateData, outputPath, config) {
|
|
227
|
+
return {
|
|
228
|
+
path: outputPath,
|
|
229
|
+
serverName: config?.serverName || templateData.title || '',
|
|
230
|
+
apis: templateData.allApis || [],
|
|
231
|
+
};
|
|
232
|
+
}
|