@sfmc-bds/cli 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/management/config.d.ts.map +1 -1
- package/dist/management/config.js +5 -1
- package/dist/management/config.js.map +2 -2
- package/dist/management/local-methods.d.ts +14 -0
- package/dist/management/local-methods.d.ts.map +1 -0
- package/dist/management/local-methods.js +7 -0
- package/dist/management/local-methods.js.map +7 -0
- package/dist/management/server.d.ts.map +1 -1
- package/dist/management/server.js +15 -3
- package/dist/management/server.js.map +2 -2
- package/dist/management/stdio.d.ts.map +1 -1
- package/dist/management/stdio.js +9 -2
- package/dist/management/stdio.js.map +2 -2
- package/dist/module-sidecars.d.ts.map +1 -1
- package/dist/module-sidecars.js +23 -0
- package/dist/module-sidecars.js.map +2 -2
- package/dist/services.d.ts.map +1 -1
- package/dist/services.js +14 -0
- package/dist/services.js.map +2 -2
- package/package.json +7 -7
- package/scripts/module-install/.sfmc-registry-cache.json +152 -29
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/management/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/management/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAiB3D,wBAAgB,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAsBjD;AACD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK9C;AACD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,UAA6D;AAClG,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAgBxD;AACD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,QAqBtE;AACD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAQvE"}
|
|
@@ -3,6 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import Ajv2020 from "ajv/dist/2020.js";
|
|
5
5
|
import { parse } from "jsonc-parser";
|
|
6
|
+
import { serverPropertyFormFields } from "@sfmc-bds/bds-tools/server-properties-fields";
|
|
6
7
|
import { resolveSdkPackageRoot, ROOT } from "../runtime.js";
|
|
7
8
|
import { resolveBdsContext } from "../pack-lifecycle.js";
|
|
8
9
|
import { readJson, stripBom } from "./domain.js";
|
|
@@ -12,6 +13,7 @@ const SCHEMA_STEM = {
|
|
|
12
13
|
"module-update.json": "module_update",
|
|
13
14
|
"pack-update.json": "pack_update"
|
|
14
15
|
};
|
|
16
|
+
const MANAGEMENT_UI_LOCALE = "zh-CN";
|
|
15
17
|
const ajv = new Ajv2020.default({ allErrors: true, strict: false });
|
|
16
18
|
const validators = /* @__PURE__ */ new Map();
|
|
17
19
|
function configFiles() {
|
|
@@ -57,7 +59,9 @@ function readDocument(key) {
|
|
|
57
59
|
const schemaFile = path.join(path.dirname(file), `${path.basename(file).replace(/\.jsonc?$/, "")}.schema.json`);
|
|
58
60
|
if (fs.existsSync(schemaFile)) schema = JSON.parse(fs.readFileSync(schemaFile, "utf8"));
|
|
59
61
|
}
|
|
60
|
-
|
|
62
|
+
const format = file.endsWith(".properties") ? "properties" : file.endsWith(".jsonc") ? "jsonc" : "json";
|
|
63
|
+
const fields = format === "properties" ? serverPropertyFormFields(MANAGEMENT_UI_LOCALE) : void 0;
|
|
64
|
+
return { key, text, revision: revision(text), ...schema ? { schema } : {}, format, affectedServices: ["db", "tunnel", "qq", "llbot", "bds"], ...fields ? { fields } : {} };
|
|
61
65
|
}
|
|
62
66
|
function validateDocument(document, text) {
|
|
63
67
|
if (Buffer.byteLength(text) > 2 * 1024 * 1024) throw new Error("\u914D\u7F6E\u6587\u4EF6\u8FC7\u5927");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/management/config.ts"],
|
|
4
|
-
"sourcesContent": ["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport Ajv2020 from \"ajv/dist/2020.js\";\nimport { parse, type ParseError } from \"jsonc-parser\";\nimport type { ConfigDocument } from \"@sfmc-bds/management\";\nimport { resolveSdkPackageRoot, ROOT } from \"../runtime.js\";\nimport { resolveBdsContext } from \"../pack-lifecycle.js\";\nimport { readJson, stripBom } from \"./domain.js\";\n\n/** \u78C1\u76D8\u4E0A\u7684\u771F\u5B9E\u6587\u4EF6\u540D\u3002schema \u6587\u4EF6\u4ECD\u7528\u4E0B\u5212\u7EBF\uFF08log_filter.schema.json\uFF09\u3002 */\nconst CORE_FILES = [\"runtime.json\", \"db_config.json\", \"qq_config.json\", \"bds_updater.json\", \"permissions.json\", \"log-filter.json\", \"module-update.json\", \"pack-update.json\"];\nconst SCHEMA_STEM: Record<string, string> = {\n \"log-filter.json\": \"log_filter\",\n \"module-update.json\": \"module_update\",\n \"pack-update.json\": \"pack_update\",\n};\nconst ajv = new Ajv2020.default({ allErrors: true, strict: false });\nconst validators = new Map<string, ReturnType<typeof ajv.compile>>();\nexport function configFiles(): Map<string, string> {\n const files = new Map(CORE_FILES.map(name => [`core/${name}`, path.join(ROOT, \"configs\", name)]));\n files.set(\"bds/server.properties\", path.join(resolveBdsContext().bdsRoot, \"server.properties\"));\n const modules = path.join(ROOT, \"modules\", \"packages\");\n if (fs.existsSync(modules)) for (const entry of fs.readdirSync(modules, { withFileTypes: true })) {\n if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;\n const configDir = path.join(modules, entry.name, \"configs\");\n if (!fs.existsSync(configDir)) continue;\n for (const filename of fs.readdirSync(configDir)) if (/^[\\w.-]+\\.jsonc?$/.test(filename)) files.set(`module/${entry.name}/${filename}`, path.join(configDir, filename));\n }\n // \u771F\u5B9E\u5B9E\u4F8B\u7684\u6A21\u5757\u914D\u7F6E\u5199\u5728 <SFMC_ROOT>/configs/<configKey>.json\uFF0C\u76EE\u5F55\u540D\u6765\u81EA catalog.configKey\u3002\n const catalog = readJson<{ modules?: { id?: string; configKey?: string }[] }>(path.join(ROOT, \"modules\", \"catalog.json\"), {});\n const taken = new Set([...files.values()].map(file => path.resolve(file)));\n for (const row of catalog.modules ?? []) {\n if (!row.id || !row.configKey || !/^[\\w.-]+$/.test(row.id) || !/^[\\w.-]+$/.test(row.configKey)) continue;\n const filename = `${row.configKey}.json`;\n const file = path.join(ROOT, \"configs\", filename);\n if (!fs.existsSync(file) || taken.has(path.resolve(file))) continue;\n files.set(`module/${row.id}/${filename}`, file);\n taken.add(path.resolve(file));\n }\n return files;\n}\nexport function configPath(key: string): string {\n const file = configFiles().get(key);\n if (!file) throw Object.assign(new Error(\"\u914D\u7F6E\u4E0D\u5728\u5141\u8BB8\u7F16\u8F91\u7684\u5217\u8868\u4E2D\"), { code: \"validation\" });\n if (fs.existsSync(file) && fs.lstatSync(file).isSymbolicLink()) throw new Error(\"\u4E0D\u80FD\u901A\u8FC7\u914D\u7F6E\u6587\u4EF6\u94FE\u63A5\u5199\u5165\u5176\u4ED6\u6587\u4EF6\");\n return file;\n}\nexport function revision(text: string) { return createHash(\"sha256\").update(text).digest(\"hex\"); }\nexport function readDocument(key: string): ConfigDocument {\n const file = configPath(key);\n const text = fs.existsSync(file) ? stripBom(fs.readFileSync(file, \"utf8\")) : \"\";\n let schema: object | undefined;\n if (key.startsWith(\"core/\")) {\n const name = SCHEMA_STEM[path.basename(file)] ?? path.basename(file, \".json\");\n const schemaFile = path.join(resolveSdkPackageRoot(), \"schemas\", `${name}.schema.json`);\n if (fs.existsSync(schemaFile)) schema = JSON.parse(fs.readFileSync(schemaFile, \"utf8\")) as object;\n } else if (key.startsWith(\"module/\")) {\n const schemaFile = path.join(path.dirname(file), `${path.basename(file).replace(/\\.jsonc?$/, \"\")}.schema.json`);\n if (fs.existsSync(schemaFile)) schema = JSON.parse(fs.readFileSync(schemaFile, \"utf8\")) as object;\n }\n
|
|
5
|
-
"mappings": "AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,YAAY,kBAAkB;AACvC,OAAO,aAAa;AACpB,SAAS,aAA8B;AAEvC,SAAS,uBAAuB,YAAY;AAC5C,SAAS,yBAAyB;AAClC,SAAS,UAAU,gBAAgB;AAGnC,MAAM,aAAa,CAAC,gBAAgB,kBAAkB,kBAAkB,oBAAoB,oBAAoB,mBAAmB,sBAAsB,kBAAkB;AAC3K,MAAM,cAAsC;AAAA,EAC1C,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,oBAAoB;AACtB;
|
|
4
|
+
"sourcesContent": ["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport Ajv2020 from \"ajv/dist/2020.js\";\nimport { parse, type ParseError } from \"jsonc-parser\";\nimport type { ConfigDocument } from \"@sfmc-bds/management\";\nimport { serverPropertyFormFields } from \"@sfmc-bds/bds-tools/server-properties-fields\";\nimport { resolveSdkPackageRoot, ROOT } from \"../runtime.js\";\nimport { resolveBdsContext } from \"../pack-lifecycle.js\";\nimport { readJson, stripBom } from \"./domain.js\";\n\n/** \u78C1\u76D8\u4E0A\u7684\u771F\u5B9E\u6587\u4EF6\u540D\u3002schema \u6587\u4EF6\u4ECD\u7528\u4E0B\u5212\u7EBF\uFF08log_filter.schema.json\uFF09\u3002 */\nconst CORE_FILES = [\"runtime.json\", \"db_config.json\", \"qq_config.json\", \"bds_updater.json\", \"permissions.json\", \"log-filter.json\", \"module-update.json\", \"pack-update.json\"];\nconst SCHEMA_STEM: Record<string, string> = {\n \"log-filter.json\": \"log_filter\",\n \"module-update.json\": \"module_update\",\n \"pack-update.json\": \"pack_update\",\n};\n/** \u7BA1\u7406\u754C\u9762\uFF08\u684C\u9762\u7AEF\u3001\u5C0F\u7A0B\u5E8F\uFF09\u7684\u8BED\u8A00\uFF1Bserver.properties \u8868\u5355\u5B57\u6BB5\u7684\u540D\u79F0\u4E0E\u8BF4\u660E\u6309\u6B64\u751F\u6210\u3002\u754C\u9762\u76EE\u524D\u53EA\u6709\u7B80\u4F53\u4E2D\u6587\u3002 */\nconst MANAGEMENT_UI_LOCALE = \"zh-CN\";\nconst ajv = new Ajv2020.default({ allErrors: true, strict: false });\nconst validators = new Map<string, ReturnType<typeof ajv.compile>>();\nexport function configFiles(): Map<string, string> {\n const files = new Map(CORE_FILES.map(name => [`core/${name}`, path.join(ROOT, \"configs\", name)]));\n files.set(\"bds/server.properties\", path.join(resolveBdsContext().bdsRoot, \"server.properties\"));\n const modules = path.join(ROOT, \"modules\", \"packages\");\n if (fs.existsSync(modules)) for (const entry of fs.readdirSync(modules, { withFileTypes: true })) {\n if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;\n const configDir = path.join(modules, entry.name, \"configs\");\n if (!fs.existsSync(configDir)) continue;\n for (const filename of fs.readdirSync(configDir)) if (/^[\\w.-]+\\.jsonc?$/.test(filename)) files.set(`module/${entry.name}/${filename}`, path.join(configDir, filename));\n }\n // \u771F\u5B9E\u5B9E\u4F8B\u7684\u6A21\u5757\u914D\u7F6E\u5199\u5728 <SFMC_ROOT>/configs/<configKey>.json\uFF0C\u76EE\u5F55\u540D\u6765\u81EA catalog.configKey\u3002\n const catalog = readJson<{ modules?: { id?: string; configKey?: string }[] }>(path.join(ROOT, \"modules\", \"catalog.json\"), {});\n const taken = new Set([...files.values()].map(file => path.resolve(file)));\n for (const row of catalog.modules ?? []) {\n if (!row.id || !row.configKey || !/^[\\w.-]+$/.test(row.id) || !/^[\\w.-]+$/.test(row.configKey)) continue;\n const filename = `${row.configKey}.json`;\n const file = path.join(ROOT, \"configs\", filename);\n if (!fs.existsSync(file) || taken.has(path.resolve(file))) continue;\n files.set(`module/${row.id}/${filename}`, file);\n taken.add(path.resolve(file));\n }\n return files;\n}\nexport function configPath(key: string): string {\n const file = configFiles().get(key);\n if (!file) throw Object.assign(new Error(\"\u914D\u7F6E\u4E0D\u5728\u5141\u8BB8\u7F16\u8F91\u7684\u5217\u8868\u4E2D\"), { code: \"validation\" });\n if (fs.existsSync(file) && fs.lstatSync(file).isSymbolicLink()) throw new Error(\"\u4E0D\u80FD\u901A\u8FC7\u914D\u7F6E\u6587\u4EF6\u94FE\u63A5\u5199\u5165\u5176\u4ED6\u6587\u4EF6\");\n return file;\n}\nexport function revision(text: string) { return createHash(\"sha256\").update(text).digest(\"hex\"); }\nexport function readDocument(key: string): ConfigDocument {\n const file = configPath(key);\n const text = fs.existsSync(file) ? stripBom(fs.readFileSync(file, \"utf8\")) : \"\";\n let schema: object | undefined;\n if (key.startsWith(\"core/\")) {\n const name = SCHEMA_STEM[path.basename(file)] ?? path.basename(file, \".json\");\n const schemaFile = path.join(resolveSdkPackageRoot(), \"schemas\", `${name}.schema.json`);\n if (fs.existsSync(schemaFile)) schema = JSON.parse(fs.readFileSync(schemaFile, \"utf8\")) as object;\n } else if (key.startsWith(\"module/\")) {\n const schemaFile = path.join(path.dirname(file), `${path.basename(file).replace(/\\.jsonc?$/, \"\")}.schema.json`);\n if (fs.existsSync(schemaFile)) schema = JSON.parse(fs.readFileSync(schemaFile, \"utf8\")) as object;\n }\n const format = file.endsWith(\".properties\") ? \"properties\" : file.endsWith(\".jsonc\") ? \"jsonc\" : \"json\";\n // server.properties \u6CA1\u6709 Schema\uFF0C\u9644\u5E26 bds-tools \u7EF4\u62A4\u7684\u5B8C\u6574\u5B57\u6BB5\u6E05\u5355\u4F9B\u8868\u5355\u89C6\u56FE\u4F7F\u7528\n const fields = format === \"properties\" ? serverPropertyFormFields(MANAGEMENT_UI_LOCALE) : undefined;\n return { key, text, revision: revision(text), ...(schema ? { schema } : {}), format, affectedServices: [\"db\", \"tunnel\", \"qq\", \"llbot\", \"bds\"], ...(fields ? { fields } : {}) };\n}\nexport function validateDocument(document: ConfigDocument, text: string) {\n if (Buffer.byteLength(text) > 2 * 1024 * 1024) throw new Error(\"\u914D\u7F6E\u6587\u4EF6\u8FC7\u5927\");\n if (document.format === \"properties\") {\n for (const line of text.split(/\\r?\\n/)) if (line.trim() && !line.trim().startsWith(\"#\") && !/^[^=\\r\\n]+=.*$/.test(line)) throw new Error(\"server.properties \u5305\u542B\u975E\u6CD5\u914D\u7F6E\u884C\");\n return;\n }\n const errors: ParseError[] = [];\n const value: unknown = parse(text, errors, { allowTrailingComma: document.format === \"jsonc\", disallowComments: document.format === \"json\" });\n if (errors.length) throw Object.assign(new Error(\"\u914D\u7F6E\u8BED\u6CD5\u9519\u8BEF\"), { code: \"validation\", details: errors });\n if (document.schema) {\n // \u4FDD\u7559\u5DF2\u6709\u672A\u77E5\u5B57\u6BB5\uFF1B\u53EA\u4ECE\u6821\u9A8C\u526F\u672C\u6392\u9664\u672A\u4FEE\u6539\u7684\u672A\u77E5\u5B57\u6BB5\uFF0C\u4FDD\u5B58\u7684\u539F\u6587\u4ECD\u5B8C\u5168\u4FDD\u7559\u3002\n const schemaObject = document.schema as { additionalProperties?: boolean; properties?: Record<string, unknown> };\n if (schemaObject.additionalProperties === false && value && typeof value === \"object\" && !Array.isArray(value)) {\n const previous = parse(document.text || \"{}\") as Record<string, unknown>;\n for (const key of Object.keys(value)) if (!(key in (schemaObject.properties ?? {})) && previous && key in previous && JSON.stringify(previous[key]) === JSON.stringify((value as Record<string, unknown>)[key])) delete (value as Record<string, unknown>)[key];\n }\n const hash = revision(JSON.stringify(document.schema));\n let validator = validators.get(hash);\n if (!validator) { const schema = { ...document.schema } as Record<string, unknown>; delete schema.$id; validator = ajv.compile(schema); validators.set(hash, validator); }\n if (!validator(value)) throw Object.assign(new Error(\"\u914D\u7F6E\u4E0D\u7B26\u5408 Schema\"), { code: \"validation\", details: validator.errors });\n }\n}\nexport function saveDocument(key: string, expected: string, text: string) {\n const document = readDocument(key);\n if (document.revision !== expected) throw Object.assign(new Error(\"\u914D\u7F6E\u5DF2\u88AB\u5176\u4ED6\u64CD\u4F5C\u4FEE\u6539\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\"), { code: \"conflict\" });\n validateDocument(document, text);\n const file = configPath(key); const temp = `${file}.${randomUUID()}.tmp`;\n fs.mkdirSync(path.dirname(file), { recursive: true });\n fs.writeFileSync(temp, text, { mode: 0o600 }); fs.renameSync(temp, file);\n return document;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* local-methods.ts — 管理通道在 stdio 进程内直接作答的只读方法
|
|
3
|
+
*
|
|
4
|
+
* 使用场景:stdio.ts 收到这些方法时不转发给常驻守护进程,而是用磁盘上的新代码读取数据库,
|
|
5
|
+
* 平台升级后不必重启仍在托管服务的守护进程即可使用;server.ts 握手时声明对应能力。
|
|
6
|
+
* 守护进程握手结果由旧代码生成时,stdio.ts 也会补上 LOCAL_CAPABILITIES。
|
|
7
|
+
* 新增此类只读方法时在这里登记(OCP)。
|
|
8
|
+
*/
|
|
9
|
+
import type { ManagementCapability } from "@sfmc-bds/management";
|
|
10
|
+
/** 在 stdio 进程内直接分派给 dispatchManagement 的方法 */
|
|
11
|
+
export declare const LOCAL_METHODS: ReadonlySet<string>;
|
|
12
|
+
/** 由本地方法提供、需要在握手中声明的能力 */
|
|
13
|
+
export declare const LOCAL_CAPABILITIES: readonly ManagementCapability[];
|
|
14
|
+
//# sourceMappingURL=local-methods.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-methods.d.ts","sourceRoot":"","sources":["../../src/management/local-methods.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,oBAAoB,EAAoB,MAAM,sBAAsB,CAAC;AAEnF,8CAA8C;AAC9C,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CAAmF,CAAC;AAElI,0BAA0B;AAC1B,eAAO,MAAM,kBAAkB,EAAE,SAAS,oBAAoB,EAAiB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/management/local-methods.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * local-methods.ts \u2014 \u7BA1\u7406\u901A\u9053\u5728 stdio \u8FDB\u7A0B\u5185\u76F4\u63A5\u4F5C\u7B54\u7684\u53EA\u8BFB\u65B9\u6CD5\n *\n * \u4F7F\u7528\u573A\u666F\uFF1Astdio.ts \u6536\u5230\u8FD9\u4E9B\u65B9\u6CD5\u65F6\u4E0D\u8F6C\u53D1\u7ED9\u5E38\u9A7B\u5B88\u62A4\u8FDB\u7A0B\uFF0C\u800C\u662F\u7528\u78C1\u76D8\u4E0A\u7684\u65B0\u4EE3\u7801\u8BFB\u53D6\u6570\u636E\u5E93\uFF0C\n * \u5E73\u53F0\u5347\u7EA7\u540E\u4E0D\u5FC5\u91CD\u542F\u4ECD\u5728\u6258\u7BA1\u670D\u52A1\u7684\u5B88\u62A4\u8FDB\u7A0B\u5373\u53EF\u4F7F\u7528\uFF1Bserver.ts \u63E1\u624B\u65F6\u58F0\u660E\u5BF9\u5E94\u80FD\u529B\u3002\n * \u5B88\u62A4\u8FDB\u7A0B\u63E1\u624B\u7ED3\u679C\u7531\u65E7\u4EE3\u7801\u751F\u6210\u65F6\uFF0Cstdio.ts \u4E5F\u4F1A\u8865\u4E0A LOCAL_CAPABILITIES\u3002\n * \u65B0\u589E\u6B64\u7C7B\u53EA\u8BFB\u65B9\u6CD5\u65F6\u5728\u8FD9\u91CC\u767B\u8BB0\uFF08OCP\uFF09\u3002\n */\nimport type { ManagementCapability, ManagementMethod } from \"@sfmc-bds/management\";\n\n/** \u5728 stdio \u8FDB\u7A0B\u5185\u76F4\u63A5\u5206\u6D3E\u7ED9 dispatchManagement \u7684\u65B9\u6CD5 */\nexport const LOCAL_METHODS: ReadonlySet<string> = new Set<ManagementMethod>([\"players.list\", \"activity.query\", \"activity.stats\"]);\n\n/** \u7531\u672C\u5730\u65B9\u6CD5\u63D0\u4F9B\u3001\u9700\u8981\u5728\u63E1\u624B\u4E2D\u58F0\u660E\u7684\u80FD\u529B */\nexport const LOCAL_CAPABILITIES: readonly ManagementCapability[] = [\"activity\"];\n"],
|
|
5
|
+
"mappings": "AAWO,MAAM,gBAAqC,oBAAI,IAAsB,CAAC,gBAAgB,kBAAkB,gBAAgB,CAAC;AAGzH,MAAM,qBAAsD,CAAC,UAAU;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/management/server.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAA6C,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/management/server.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAA6C,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAQ/H,OAAO,EAAE,SAAS,EAAgC,MAAM,YAAY,CAAC;AAuBrE,wBAAgB,eAAe,cAQ9B;AACD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,2BAA+E;AAsD3J,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAyNrF"}
|
|
@@ -4,6 +4,7 @@ import os from "node:os";
|
|
|
4
4
|
import { EventEmitter } from "node:events";
|
|
5
5
|
import { LOG_TAIL_MAX, MANAGEMENT_PROTOCOL_VERSION } from "@sfmc-bds/management";
|
|
6
6
|
import { readQqBindings } from "@sfmc-bds/db-server/qq-bindings";
|
|
7
|
+
import { parseActivityFilter, parseActivityPaging, readActivityPage, readActivityStats } from "@sfmc-bds/db-server/activity-log";
|
|
7
8
|
import { ROOT, isRuntimeInitialized, spawnService } from "../runtime.js";
|
|
8
9
|
import { queryServicesRuntimeLocal, services, START_ORDER, SERVICE_NAMES, refreshServices, onServiceStateChange } from "../services.js";
|
|
9
10
|
import { readDiskLogs, deleteStoredLogs, onLog } from "../logs.js";
|
|
@@ -19,6 +20,7 @@ import { withMaintenanceLock } from "@sfmc-bds/management/node";
|
|
|
19
20
|
import { deploymentPreflight, deploymentPort } from "./deployment.js";
|
|
20
21
|
import { resolveBdsContext } from "../pack-lifecycle.js";
|
|
21
22
|
import { readRuntimeMetrics } from "./metrics-read.js";
|
|
23
|
+
import { LOCAL_CAPABILITIES } from "./local-methods.js";
|
|
22
24
|
import { importPacks, planPackImport, readImportFilenames } from "./pack-import.js";
|
|
23
25
|
const events = new EventEmitter();
|
|
24
26
|
function deploymentInitialized() {
|
|
@@ -67,11 +69,17 @@ async function rebuildModules() {
|
|
|
67
69
|
if (!deploy.ok) throw new Error(deploy.message);
|
|
68
70
|
return { changed: true };
|
|
69
71
|
}
|
|
72
|
+
function dbConfig() {
|
|
73
|
+
return readJson(path.join(ROOT, "configs", "db_config.json"), {});
|
|
74
|
+
}
|
|
75
|
+
function businessDatabase(cfg = dbConfig()) {
|
|
76
|
+
return path.resolve(ROOT, typeof cfg.dbDir === "string" && cfg.dbDir.trim() ? cfg.dbDir : "data/sfmc_data.db");
|
|
77
|
+
}
|
|
70
78
|
async function players() {
|
|
71
79
|
const files = playerFiles();
|
|
72
80
|
const allowlist = readJson(files.allowlist, []);
|
|
73
|
-
const cfg =
|
|
74
|
-
const database =
|
|
81
|
+
const cfg = dbConfig();
|
|
82
|
+
const database = businessDatabase(cfg);
|
|
75
83
|
let data = {};
|
|
76
84
|
try {
|
|
77
85
|
const response = await fetch(`http://127.0.0.1:${cfg.db_port ?? 3001}/api/sfmc/status`, { headers: cfg.http_auth ? { authorization: `Bearer ${cfg.http_auth}` } : {}, signal: AbortSignal.timeout(5e3) });
|
|
@@ -100,7 +108,7 @@ async function dispatchManagement(request) {
|
|
|
100
108
|
const store = managementTasks();
|
|
101
109
|
switch (request.method) {
|
|
102
110
|
case "handshake":
|
|
103
|
-
return { protocolVersion: MANAGEMENT_PROTOCOL_VERSION, platformVersion: platformVersion(), host: { os: process.platform === "win32" ? "windows" : process.platform, arch: process.arch, release: os.release() }, root: ROOT, capabilities: ["services", "logs", "logs-range", "modules", "config", "packs", "players", "updates", "operations", "metrics", "manual-restart", "manual-backup", "pack-import-plan", "pack-icons", "pack-uninstall", "backup-delete", "pack-import-batch", "pack-version"], daemonPid: process.pid, daemonStartedAt: new Date(Date.now() - process.uptime() * 1e3).toISOString(), initialized: deploymentInitialized() };
|
|
111
|
+
return { protocolVersion: MANAGEMENT_PROTOCOL_VERSION, platformVersion: platformVersion(), host: { os: process.platform === "win32" ? "windows" : process.platform, arch: process.arch, release: os.release() }, root: ROOT, capabilities: ["services", "logs", "logs-range", "modules", "config", "packs", "players", "updates", "operations", "metrics", "manual-restart", "manual-backup", "pack-import-plan", "pack-icons", "pack-uninstall", "backup-delete", "pack-import-batch", "pack-version", ...LOCAL_CAPABILITIES], daemonPid: process.pid, daemonStartedAt: new Date(Date.now() - process.uptime() * 1e3).toISOString(), initialized: deploymentInitialized() };
|
|
104
112
|
case "events.subscribe":
|
|
105
113
|
return { subscribed: true };
|
|
106
114
|
case "services.list":
|
|
@@ -289,6 +297,10 @@ async function dispatchManagement(request) {
|
|
|
289
297
|
return players();
|
|
290
298
|
case "metrics.read":
|
|
291
299
|
return readRuntimeMetrics(request.params);
|
|
300
|
+
case "activity.query":
|
|
301
|
+
return readActivityPage(businessDatabase(), parseActivityFilter(p), parseActivityPaging(p));
|
|
302
|
+
case "activity.stats":
|
|
303
|
+
return readActivityStats(businessDatabase(), parseActivityFilter(p));
|
|
292
304
|
case "players.apply":
|
|
293
305
|
return store.submit(request.method, (context) => withStoppedServices(context, [...START_ORDER], async () => savePlayerPermissions(string(p.kind, "\u6743\u9650\u7C7B\u578B"), p.entries)));
|
|
294
306
|
case "attachment.plan":
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/management/server.ts"],
|
|
4
|
-
"sourcesContent": ["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport { EventEmitter } from \"node:events\";\nimport { LOG_TAIL_MAX, MANAGEMENT_PROTOCOL_VERSION, type ManagementRequest, type ManagementEvent } from \"@sfmc-bds/management\";\nimport { readQqBindings } from \"@sfmc-bds/db-server/qq-bindings\";\nimport { ROOT, isRuntimeInitialized, spawnService } from \"../runtime.js\";\nimport { queryServicesRuntimeLocal, services, START_ORDER, SERVICE_NAMES, refreshServices, onServiceStateChange, type ServiceName } from \"../services.js\";\nimport { readDiskLogs, deleteStoredLogs, onLog } from \"../logs.js\";\nimport { cmdModuleEnable, cmdModuleDisable } from \"../module-commands.js\";\nimport { ensureCoreConfigs } from \"@sfmc-bds/sdk/node/config\";\nimport { TaskStore, atomicJson, type TaskContext } from \"./tasks.js\";\nimport { configFiles, readDocument, revision, saveDocument, validateDocument } from \"./config.js\";\nimport { listModules, searchModules, identifier, runFetch, readJson, listPacks, togglePack, readPackIcon, uninstallPack, setPackVersion, playerFiles, savePlayerPermissions, modulePlan, applyModulePlan, moduleInstallBlock } from \"./domain.js\";\nimport { attachmentPlan, platformVersion, withStoppedServices, launchPlatformUpdate, createBackup, restoreSnapshot, deleteSnapshot, verifyRunning } from \"./maintenance.js\";\nimport { startupPlan } from \"./startup.js\";\nimport { cmdPackBuild, cmdPackDeploy } from \"../pack-lifecycle.js\";\nimport { withMaintenanceLock } from \"@sfmc-bds/management/node\";\nimport { deploymentPreflight, deploymentPort } from \"./deployment.js\";\nimport { resolveBdsContext } from \"../pack-lifecycle.js\";\nimport { readRuntimeMetrics } from \"./metrics-read.js\";\n\nimport { importPacks, planPackImport, readImportFilenames } from \"./pack-import.js\";\n\nconst events = new EventEmitter();\n/** \u7A7A\u76EE\u5F55\u4E5F\u8981\u80FD\u5B8C\u6210\u63E1\u624B\uFF0C\u4F9B\u684C\u9762\u521D\u59CB\u5316\u5411\u5BFC\u7EE7\u7EED\uFF1B\u65E7\u90E8\u7F72\u4ECD\u8BC6\u522B\u5DF2\u6709 BDS\u3002 */\nfunction deploymentInitialized(): boolean {\n if (isRuntimeInitialized()) return true;\n const config = readJson<{ bds_path?: string }>(path.join(ROOT, \"configs\", \"bds_updater.json\"), {});\n if (!config.bds_path) return false;\n return fs.existsSync(path.join(resolveBdsContext().bdsRoot, process.platform === \"win32\" ? \"bedrock_server.exe\" : \"bedrock_server\"));\n}\nlet tasks: TaskStore | undefined;\nexport function managementTasks() {\n if (!tasks) {\n tasks = new TaskStore(ROOT);\n tasks.on(\"operation\", payload => events.emit(\"event\", { type: \"event\", event: \"operation\", instanceId: ROOT, payload }));\n onLog(log => events.emit(\"event\", { type: \"event\", event: \"log\", instanceId: ROOT, payload: { ...log, time: log.time.toISOString() } }));\n onServiceStateChange(payload => events.emit(\"event\", { type: \"event\", event: \"serviceState\", instanceId: ROOT, payload }));\n }\n return tasks;\n}\nexport function onManagementEvent(callback: (event: ManagementEvent) => void) { events.on(\"event\", callback); return () => events.off(\"event\", callback); }\nfunction params(request: ManagementRequest): Record<string, unknown> {\n if (request.params === undefined) return {};\n if (!request.params || typeof request.params !== \"object\" || Array.isArray(request.params)) throw new Error(\"\u53C2\u6570\u5FC5\u987B\u4E3A\u5BF9\u8C61\");\n return request.params as Record<string, unknown>;\n}\nfunction string(value: unknown, label: string) { if (typeof value !== \"string\" || value.length > 2 * 1024 * 1024) throw new Error(`\u975E\u6CD5 ${label}`); return value; }\n/** \u89E3\u6790\u65E5\u5FD7\u67E5\u8BE2\u7528\u7684 ISO \u65F6\u95F4\u3002\u7F3A\u7701\u8FD4\u56DE undefined\u3002 */\nfunction timeBound(value: unknown, label: string): Date | undefined {\n if (value === undefined) return undefined;\n const date = new Date(string(value, label));\n if (Number.isNaN(date.getTime())) throw new Error(`\u975E\u6CD5 ${label}`);\n return date;\n}\nfunction service(value: unknown): ServiceName { if (!SERVICE_NAMES.includes(value as ServiceName)) throw new Error(\"\u672A\u77E5\u670D\u52A1\"); return value as ServiceName; }\nasync function rebuildModules() {\n const build = await cmdPackBuild([]); if (!build.ok) throw new Error(build.message);\n const deploy = await cmdPackDeploy([]); if (!deploy.ok) throw new Error(deploy.message);\n return { changed: true };\n}\n\nasync function players() {\n const files = playerFiles(); const allowlist = readJson<unknown[]>(files.allowlist, []);\n const cfg = readJson<{ db_port?: number; http_auth?: string; dbDir?: string }>(path.join(ROOT, \"configs\", \"db_config.json\"), {});\n const database = path.resolve(ROOT, typeof cfg.dbDir === \"string\" && cfg.dbDir.trim() ? cfg.dbDir : \"data/sfmc_data.db\");\n let data: { online?: { name: string }[]; updatedAt?: number } = {};\n try {\n const response = await fetch(`http://127.0.0.1:${cfg.db_port ?? 3001}/api/sfmc/status`, { headers: cfg.http_auth ? { authorization: `Bearer ${cfg.http_auth}` } : {}, signal: AbortSignal.timeout(5000) });\n if (response.ok) data = await response.json() as typeof data;\n } catch { /* \u672A\u8FDE\u63A5\u65F6\u4F7F\u7528\u672A\u77E5\u72B6\u6001 */ }\n const fresh = typeof data.updatedAt === \"number\" && Date.now() - data.updatedAt < 60_000;\n return { players: (data.online ?? []).map(row => ({ name: row.name, xuid: \"\", online: fresh ? true : null })), updatedAt: data.updatedAt ? new Date(data.updatedAt).toISOString() : \"\", fresh, allowlist, permissions: readJson<unknown[]>(files.permissions, []), sfmcPermissions: readJson<unknown[]>(files.sfmcPermissions, []), bindings: readQqBindings(database) };\n}\nasync function bdsUpdate(context: TaskContext, checkOnly = false) {\n context.phase(\"download\", checkOnly ? \"\u68C0\u67E5 BDS \u66F4\u65B0\" : \"\u66F4\u65B0 BDS\");\n const args = checkOnly ? [\"--check-only\", \"--no-notify\"] : [\"--no-start\", \"--no-notify\"];\n let output = \"\";\n await new Promise<void>((resolve, reject) => {\n const child = spawnService(\"update\", args, { stdio: \"pipe\", cwd: ROOT });\n for (const stream of [child.stdout, child.stderr]) stream?.on(\"data\", chunk => { output = (output + String(chunk)).slice(-64_000); });\n child.on(\"error\", reject); child.on(\"close\", code => code === 0 ? resolve() : reject(new Error(`BDS \u66F4\u65B0\u5931\u8D25 (${code})`)));\n });\n return { checked: checkOnly, updated: /SFMC_UPDATE_RESULT=deployed/.test(output), currentVersion: /CURRENT=([^\\r\\n]+)/.exec(output)?.[1] ?? \"unknown\", latestVersion: /LATEST=([^\\r\\n]+)/.exec(output)?.[1] ?? \"unknown\", result: /SFMC_UPDATE_RESULT=([^\\r\\n]+)/.exec(output)?.[1] ?? \"unknown\" };\n}\nexport async function dispatchManagement(request: ManagementRequest): Promise<unknown> {\n const p = params(request); const store = managementTasks();\n switch (request.method) {\n case \"handshake\": return { protocolVersion: MANAGEMENT_PROTOCOL_VERSION, platformVersion: platformVersion(), host: { os: process.platform === \"win32\" ? \"windows\" : process.platform, arch: process.arch, release: os.release() }, root: ROOT, capabilities: [\"services\", \"logs\", \"logs-range\", \"modules\", \"config\", \"packs\", \"players\", \"updates\", \"operations\", \"metrics\", \"manual-restart\", \"manual-backup\", \"pack-import-plan\", \"pack-icons\", \"pack-uninstall\", \"backup-delete\", \"pack-import-batch\", \"pack-version\"], daemonPid: process.pid, daemonStartedAt: new Date(Date.now() - process.uptime() * 1000).toISOString(), initialized: deploymentInitialized() };\n case \"events.subscribe\": return { subscribed: true };\n case \"services.list\": return { rows: await queryServicesRuntimeLocal() };\n case \"services.start\": case \"services.stop\": case \"services.restart\": {\n const requestedNames = p.name === \"all\" ? [...START_ORDER] : [service(p.name)];\n const reloadConfig = p.reloadConfig === true;\n if (reloadConfig && (p.name !== \"all\" || request.method !== \"services.restart\")) throw new Error(\"\u91CD\u65B0\u8BFB\u53D6\u914D\u7F6E\u9700\u8981\u91CD\u542F\u5168\u90E8\u670D\u52A1\");\n return store.submit(request.method, async context => {\n context.phase(\"execute\");\n const rows = await queryServicesRuntimeLocal();\n const names = p.runningOnly === true\n ? requestedNames.filter(name => rows.some(row => row.name === name && row.running))\n : requestedNames;\n if (rows.some(row => names.includes(row.name) && row.running && row.ownership === \"external\") && request.method !== \"services.start\") throw new Error(\"\u5916\u90E8\u8FDB\u7A0B\u65E0\u6CD5\u5B89\u5168\u505C\u6B62\uFF0C\u8BF7\u901A\u8FC7\u539F\u7BA1\u7406\u5668\u64CD\u4F5C\");\n if (request.method !== \"services.start\") for (const name of [...names].reverse()) await services[name].stop(false, false);\n if (reloadConfig) {\n const after = await queryServicesRuntimeLocal();\n if (after.some(row => requestedNames.includes(row.name) && row.running)) throw new Error(\"\u670D\u52A1\u672A\u5B8C\u5168\u9000\u51FA\uFF0C\u5DF2\u4E2D\u6B62\u914D\u7F6E\u5237\u65B0\");\n refreshServices();\n }\n if (request.method !== \"services.stop\") {\n if (!reloadConfig) {\n const after = await queryServicesRuntimeLocal();\n if (request.method === \"services.restart\" && after.some(row => names.includes(row.name) && row.running)) throw new Error(\"\u670D\u52A1\u672A\u5B8C\u5168\u9000\u51FA\uFF0C\u5DF2\u4E2D\u6B62\u91CD\u542F\");\n const stopped = names.filter(name => !after.some(row => row.name === name && row.running));\n if (stopped.length) refreshServices(stopped);\n }\n const outcomes = [];\n for (const name of names) outcomes.push({ name, ...(await services[name].start()) });\n await verifyRunning(outcomes.filter(row => row.status !== \"skipped\").map(row => row.name));\n return { outcomes };\n }\n return { stopped: names };\n });\n }\n case \"services.send\": {\n const name = service(p.name); const message = string(p.message, \"\u547D\u4EE4\");\n if (/[\\r\\n]/.test(message) || !message.trim()) throw new Error(\"\u4E00\u6B21\u53EA\u80FD\u53D1\u9001\u4E00\u884C\u547D\u4EE4\");\n const target = services[name]; if (!target.proc?.stdin || !target.running) throw new Error(\"\u670D\u52A1\u672A\u6258\u7BA1\u6216\u6CA1\u6709\u547D\u4EE4\u8F93\u5165\u901A\u9053\");\n return withMaintenanceLock(ROOT, async () => { target.proc!.stdin!.write(message + \"\\n\"); return { delivered: true }; });\n }\n case \"logs.tail\": {\n const since = timeBound(p.since, \"\u5F00\u59CB\u65F6\u95F4\");\n const until = timeBound(p.until, \"\u7ED3\u675F\u65F6\u95F4\");\n if (since && until && until < since) throw new Error(\"\u7ED3\u675F\u65F6\u95F4\u4E0D\u80FD\u65E9\u4E8E\u5F00\u59CB\u65F6\u95F4\");\n const limit = Math.min(LOG_TAIL_MAX, Math.max(1, Number(p.limit) || 1000));\n const ranged = Boolean(since || until);\n const entries = readDiskLogs({\n ...(ranged ? {} : { limit }),\n ...(since ? { since } : {}),\n ...(until ? { until } : {}),\n ...(Array.isArray(p.sources) ? { sources: p.sources.map(value => string(value, \"\u65E5\u5FD7\u6765\u6E90\")) } : {}),\n ...(Array.isArray(p.levels) ? { levels: p.levels as (\"info\" | \"warn\" | \"error\")[] } : {}),\n });\n const truncated = entries.length > limit;\n return { entries: (truncated ? entries.slice(entries.length - limit) : entries).map(log => ({ ...log, time: log.time.toISOString() })), ...(truncated ? { truncated: true } : {}) };\n }\n case \"logs.delete\": {\n const since = timeBound(p.since, \"\u5F00\u59CB\u65F6\u95F4\");\n const until = timeBound(p.until, \"\u7ED3\u675F\u65F6\u95F4\");\n if (!since || !until) throw new Error(\"\u5220\u9664\u65E5\u5FD7\u9700\u8981\u5F00\u59CB\u548C\u7ED3\u675F\u65F6\u95F4\");\n if (until < since) throw new Error(\"\u7ED3\u675F\u65F6\u95F4\u4E0D\u80FD\u65E9\u4E8E\u5F00\u59CB\u65F6\u95F4\");\n const source = p.source === undefined ? undefined : string(p.source, \"\u65E5\u5FD7\u6765\u6E90\");\n if (source !== undefined && (source.length > 128 || /[\\r\\n]/.test(source))) throw new Error(\"\u975E\u6CD5\u65E5\u5FD7\u6765\u6E90\");\n const text = p.text === undefined ? undefined : string(p.text, \"\u65E5\u5FD7\u6B63\u6587\");\n return deleteStoredLogs({ since, until, ...(source === undefined ? {} : { source }), ...(text === undefined ? {} : { text }) });\n }\n case \"operations.list\": return { operations: store.list().filter(row => !Array.isArray(p.statuses) || p.statuses.includes(row.status)).slice(0, Math.min(Number(p.limit) || 100, 200)) };\n case \"operations.get\": return { operation: store.get(string(p.operationId, \"\u4EFB\u52A1\u7F16\u53F7\")) };\n case \"modules.list\": return listModules();\n case \"modules.search\": return searchModules(typeof p.query === \"string\" ? p.query : \"\");\n case \"modules.install\": {\n const id = identifier(p.id);\n const linked = (await listModules()).modules.find(row => row.id === id || row.folder === id)?.linked;\n if (linked) throw new Error(\"\u4FDD\u7559\u672C\u5730\u94FE\u63A5\u6A21\u5757\uFF0C\u4E0D\u901A\u8FC7\u5305\u5B89\u88C5\u6216\u5378\u8F7D\u8986\u76D6\u5F00\u53D1\u76EE\u5F55\");\n const block = await moduleInstallBlock(id);\n if (block) throw new Error(block);\n return store.submit(request.method, async context => {\n context.phase(\"download\", \"\u4E0B\u8F7D\u5E76\u5B89\u88C5\u6A21\u5757\uFF0C\u670D\u52A1\u5668\u4FDD\u6301\u8FD0\u884C\");\n const args = [\"install\", id];\n if (typeof p.source === \"string\" && p.source) args.push(\"--from\", p.source);\n await runFetch(args);\n context.phase(\"execute\", \"\u91CD\u5EFA\u884C\u4E3A\u5305\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS\");\n return { ...(await rebuildModules()), restartRequired: true };\n });\n }\n case \"modules.uninstall\": case \"modules.toggle\": {\n const id = identifier(p.id);\n if (request.method !== \"modules.toggle\") {\n const linked = (await listModules()).modules.find(row => row.id === id || row.folder === id)?.linked;\n if (linked) throw new Error(\"\u4FDD\u7559\u672C\u5730\u94FE\u63A5\u6A21\u5757\uFF0C\u4E0D\u901A\u8FC7\u5305\u5B89\u88C5\u6216\u5378\u8F7D\u8986\u76D6\u5F00\u53D1\u76EE\u5F55\");\n }\n return store.submit(request.method, async context => {\n context.phase(\"execute\", \"\u66F4\u65B0\u6A21\u5757\u5E76\u91CD\u5EFA\u884C\u4E3A\u5305\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS\");\n if (request.method === \"modules.toggle\") {\n const result = await (p.enabled === true ? cmdModuleEnable([id]) : cmdModuleDisable([id])); if (!result.ok) throw new Error(result.message);\n } else {\n await runFetch([\"uninstall\", id]);\n }\n return { ...(await rebuildModules()), restartRequired: true };\n });\n }\n case \"config.list\": return { keys: [...configFiles().keys()] };\n case \"config.read\": return readDocument(string(p.key, \"\u914D\u7F6E\u540D\u79F0\"));\n case \"config.save\": {\n const key = string(p.key, \"\u914D\u7F6E\u540D\u79F0\"); const text = string(p.text, \"\u914D\u7F6E\u5185\u5BB9\"); const expected = string(p.revision, \"\u914D\u7F6E\u7248\u672C\");\n const document = readDocument(key); validateDocument(document, text);\n if (document.revision !== expected) throw Object.assign(new Error(\"\u914D\u7F6E\u5DF2\u53D8\u66F4\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\"), { code: \"conflict\" });\n return store.submit(request.method, async context => {\n context.phase(\"execute\", \"\u4FDD\u5B58\u914D\u7F6E\u6587\u4EF6\uFF0C\u4E0D\u91CD\u542F\u670D\u52A1\");\n saveDocument(key, expected, text);\n return { saved: true, revision: revision(text), restartRequired: true };\n });\n }\n case \"config.apply\": {\n const key = string(p.key, \"\u914D\u7F6E\u540D\u79F0\"); const text = string(p.text, \"\u914D\u7F6E\u5185\u5BB9\"); const expected = string(p.revision, \"\u914D\u7F6E\u7248\u672C\");\n const document = readDocument(key); validateDocument(document, text);\n if (document.revision !== expected) throw Object.assign(new Error(\"\u914D\u7F6E\u5DF2\u53D8\u66F4\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\"), { code: \"conflict\" });\n return store.submit(request.method, async context => {\n let saved = false;\n try { return await withStoppedServices(context, [...START_ORDER], async () => {\n saveDocument(key, expected, text); context.phase(\"apply\", \"\u6587\u4EF6\u5DF2\u4FDD\u5B58\uFF0C\u6B63\u5728\u5E94\u7528\u8FD0\u884C\u914D\u7F6E\");\n saved = true;\n refreshServices(); return { saved: true, revision: readDocument(key).revision, applied: true };\n }); } catch (error) { throw Object.assign(new Error(`${saved ? \"\u6587\u4EF6\u5DF2\u4FDD\u5B58\uFF0C\u8FD0\u884C\u65F6\u5E94\u7528\u5931\u8D25\" : \"\u914D\u7F6E\u672A\u4FDD\u5B58\"}: ${error instanceof Error ? error.message : String(error)}`), { code: \"io\", details: { saved, applied: false } }); }\n });\n }\n case \"packs.list\": return listPacks();\n case \"packs.icon\": return readPackIcon(identifier(p.id));\n case \"packs.import.plan\": return planPackImport(identifier(p.filename));\n case \"packs.import\": {\n const names = readImportFilenames(p);\n return store.submit(request.method, async context => {\n context.phase(\"execute\", names.length > 1 ? `\u5BFC\u5165 ${names.length} \u4E2A\u4E16\u754C\u5305\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS` : \"\u5BFC\u5165\u4E16\u754C\u5305\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS\");\n return importPacks(names, { force: p.force === true, ...(p.revision === undefined ? {} : { revision: string(p.revision, \"\u5BFC\u5165\u8BA1\u5212\u7248\u672C\") }) });\n });\n }\n case \"packs.toggle\": return store.submit(request.method, async context => {\n context.phase(\"execute\", \"\u4FDD\u5B58\u4E16\u754C\u5305\u72B6\u6001\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS\");\n return togglePack(identifier(p.id), p.enabled === true);\n });\n case \"packs.uninstall\": return store.submit(request.method, async context => {\n context.phase(\"execute\", \"\u5378\u8F7D\u4E16\u754C\u5305\u5E76\u79FB\u5165\u56DE\u6536\u7AD9\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS\");\n return uninstallPack(identifier(p.id));\n });\n case \"packs.version\": {\n const id = identifier(p.id);\n const version = p.version;\n return store.submit(request.method, async context => {\n context.phase(\"execute\", \"\u5199\u5165\u8D44\u6E90\u5305\u7248\u672C\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS\");\n return setPackVersion(id, version);\n });\n }\n case \"players.list\": return players();\n case \"metrics.read\": return readRuntimeMetrics(request.params);\n case \"players.apply\": return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], async () => savePlayerPermissions(string(p.kind, \"\u6743\u9650\u7C7B\u578B\"), p.entries)));\n case \"attachment.plan\": return attachmentPlan();\n case \"attachment.apply\": return store.submit(request.method, async context => {\n const plan = await attachmentPlan(false);\n if (p.targetVersion !== undefined && p.targetVersion !== plan.targetVersion) throw Object.assign(new Error(\"\u76EE\u6807\u7248\u672C\u5DF2\u53D8\u66F4\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u66F4\u65B0\u65E5\u5FD7\u540E\u786E\u8BA4\"), { code: \"conflict\" });\n if (plan.externalServices.length) throw new Error(\"\u65E0\u6CD5\u53EF\u9760\u8FC1\u79FB\u5916\u90E8\u8FDB\u7A0B\uFF1B\u8BF7\u5148\u901A\u8FC7\u539F\u7BA1\u7406\u5668\u4F18\u96C5\u505C\u670D\");\n if (plan.upgradeRequired) return launchPlatformUpdate(store, context, plan.targetVersion);\n return { attached: true, version: plan.currentVersion, development: plan.development };\n });\n case \"updates.check\": {\n const results = await Promise.allSettled([attachmentPlan(), modulePlan(), bdsUpdate({ id: \"check\", phase: () => {} }, true)]);\n return Object.fromEntries(results.map((result, index) => [[\"platform\", \"modules\", \"bds\"][index], result.status === \"fulfilled\" ? result.value : { error: String(result.reason) }]));\n }\n case \"updates.run\": {\n if (p.kind === \"platform\") return store.submit(request.method, async context => { const plan = await attachmentPlan(false); if (p.targetVersion !== undefined && p.targetVersion !== plan.targetVersion) throw Object.assign(new Error(\"\u76EE\u6807\u7248\u672C\u5DF2\u53D8\u66F4\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u66F4\u65B0\u65E5\u5FD7\u540E\u786E\u8BA4\"), { code: \"conflict\" }); return plan.upgradeRequired ? launchPlatformUpdate(store, context, plan.targetVersion) : { upToDate: true, version: plan.currentVersion }; });\n if (p.kind === \"modules\") return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], async () => { const result = await applyModulePlan(Array.isArray(p.ids) ? p.ids.map(identifier) : []); await rebuildModules(); return result; }));\n if (p.kind === \"bds\") return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], () => bdsUpdate(context)));\n throw new Error(\"\u672A\u77E5\u66F4\u65B0\u7C7B\u578B\");\n }\n case \"deployment.create\": {\n if (p.acceptEula !== true) throw new Error(\"\u521B\u5EFA\u90E8\u7F72\u524D\u5FC5\u987B\u786E\u8BA4 BDS \u4F7F\u7528\u6761\u6B3E\");\n return store.submit(request.method, async context => {\n if (isRuntimeInitialized()) throw new Error(\"\u76EE\u5F55\u5DF2\u7ECF\u521D\u59CB\u5316\uFF0C\u4E0D\u8986\u76D6\u5DF2\u6709\u90E8\u7F72\");\n const ports = { db: deploymentPort(p.dbPort, 3001), bds: deploymentPort(p.bdsPort, 19132), bds6: deploymentPort(p.bdsPort6, 19133) };\n context.phase(\"preflight\", \"\u68C0\u67E5\u76EE\u5F55\u3001\u78C1\u76D8\u7A7A\u95F4\u548C TCP\uFF0FUDP \u7AEF\u53E3\"); await deploymentPreflight(ports);\n context.phase(\"prepare\"); ensureCoreConfigs(ROOT, [\"db_config\", \"qq_config\", \"bds_updater\", \"permissions\", \"qq_link\"]);\n const updater = path.join(ROOT, \"configs\", \"bds_updater.json\");\n atomicJson(updater, { ...readJson(updater, {}), bds_path: \"BDS\", backup_dir: \"backups\" });\n const dbFile = path.join(ROOT, \"configs\", \"db_config.json\"); atomicJson(dbFile, { ...readJson(dbFile, {}), db_port: ports.db });\n fs.mkdirSync(path.join(ROOT, \"modules\", \"packages\"), { recursive: true });\n await bdsUpdate(context);\n const properties = path.join(ROOT, \"BDS\", \"server.properties\");\n let text = fs.readFileSync(properties, \"utf8\");\n for (const [key, port] of [[\"server-port\", ports.bds], [\"server-portv6\", ports.bds6]] as const) text = text.replace(new RegExp(`^${key}=.*$`, \"m\"), `${key}=${port}`);\n fs.writeFileSync(properties, text);\n await rebuildModules();\n refreshServices(); context.phase(\"start\");\n const started: ServiceName[] = [];\n try { for (const name of START_ORDER) { const result = await services[name].start(); if (result.status !== \"skipped\") started.push(name); } await verifyRunning(started); }\n catch (error) { for (const name of [...START_ORDER].reverse()) await services[name].stop(false, false).catch(() => {}); throw error; }\n atomicJson(path.join(ROOT, \"configs\", \"runtime.json\"), { ...readJson(path.join(ROOT, \"configs\", \"runtime.json\"), {}), initialized_at: new Date().toISOString() });\n return { created: true, rows: await queryServicesRuntimeLocal() };\n });\n }\n case \"backups.list\": { const directory = path.join(ROOT, \".sfmc\", \"backups\"); return { backups: fs.existsSync(directory) ? fs.readdirSync(directory).filter(id => fs.existsSync(path.join(directory, id, \"manifest.json\"))) : [] }; }\n case \"backups.create\": return store.submit(request.method, context => createBackup(context));\n case \"backups.restore\": {\n if (p.confirmDataLoss !== true) throw new Error(\"\u6062\u590D\u6570\u636E\u9700\u8981\u660E\u786E\u786E\u8BA4\u4E22\u5F03\u5907\u4EFD\u4E4B\u540E\u7684\u53D8\u66F4\");\n return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], () => restoreSnapshot(identifier(p.id), context.phase)));\n }\n case \"backups.delete\": return store.submit(request.method, async context => {\n context.phase(\"execute\", \"\u5220\u9664\u5907\u4EFD\u76EE\u5F55\");\n return deleteSnapshot(identifier(p.id));\n });\n case \"startup.plan\": return startupPlan();\n default: throw Object.assign(new Error(`\u4E0D\u652F\u6301\u7684\u7BA1\u7406\u65B9\u6CD5: ${request.method}`), { code: \"unsupported\" });\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport { EventEmitter } from \"node:events\";\nimport { LOG_TAIL_MAX, MANAGEMENT_PROTOCOL_VERSION, type ManagementRequest, type ManagementEvent } from \"@sfmc-bds/management\";\nimport { readQqBindings } from \"@sfmc-bds/db-server/qq-bindings\";\nimport { parseActivityFilter, parseActivityPaging, readActivityPage, readActivityStats } from \"@sfmc-bds/db-server/activity-log\";\nimport { ROOT, isRuntimeInitialized, spawnService } from \"../runtime.js\";\nimport { queryServicesRuntimeLocal, services, START_ORDER, SERVICE_NAMES, refreshServices, onServiceStateChange, type ServiceName } from \"../services.js\";\nimport { readDiskLogs, deleteStoredLogs, onLog } from \"../logs.js\";\nimport { cmdModuleEnable, cmdModuleDisable } from \"../module-commands.js\";\nimport { ensureCoreConfigs } from \"@sfmc-bds/sdk/node/config\";\nimport { TaskStore, atomicJson, type TaskContext } from \"./tasks.js\";\nimport { configFiles, readDocument, revision, saveDocument, validateDocument } from \"./config.js\";\nimport { listModules, searchModules, identifier, runFetch, readJson, listPacks, togglePack, readPackIcon, uninstallPack, setPackVersion, playerFiles, savePlayerPermissions, modulePlan, applyModulePlan, moduleInstallBlock } from \"./domain.js\";\nimport { attachmentPlan, platformVersion, withStoppedServices, launchPlatformUpdate, createBackup, restoreSnapshot, deleteSnapshot, verifyRunning } from \"./maintenance.js\";\nimport { startupPlan } from \"./startup.js\";\nimport { cmdPackBuild, cmdPackDeploy } from \"../pack-lifecycle.js\";\nimport { withMaintenanceLock } from \"@sfmc-bds/management/node\";\nimport { deploymentPreflight, deploymentPort } from \"./deployment.js\";\nimport { resolveBdsContext } from \"../pack-lifecycle.js\";\nimport { readRuntimeMetrics } from \"./metrics-read.js\";\nimport { LOCAL_CAPABILITIES } from \"./local-methods.js\";\n\nimport { importPacks, planPackImport, readImportFilenames } from \"./pack-import.js\";\n\nconst events = new EventEmitter();\n/** \u7A7A\u76EE\u5F55\u4E5F\u8981\u80FD\u5B8C\u6210\u63E1\u624B\uFF0C\u4F9B\u684C\u9762\u521D\u59CB\u5316\u5411\u5BFC\u7EE7\u7EED\uFF1B\u65E7\u90E8\u7F72\u4ECD\u8BC6\u522B\u5DF2\u6709 BDS\u3002 */\nfunction deploymentInitialized(): boolean {\n if (isRuntimeInitialized()) return true;\n const config = readJson<{ bds_path?: string }>(path.join(ROOT, \"configs\", \"bds_updater.json\"), {});\n if (!config.bds_path) return false;\n return fs.existsSync(path.join(resolveBdsContext().bdsRoot, process.platform === \"win32\" ? \"bedrock_server.exe\" : \"bedrock_server\"));\n}\nlet tasks: TaskStore | undefined;\nexport function managementTasks() {\n if (!tasks) {\n tasks = new TaskStore(ROOT);\n tasks.on(\"operation\", payload => events.emit(\"event\", { type: \"event\", event: \"operation\", instanceId: ROOT, payload }));\n onLog(log => events.emit(\"event\", { type: \"event\", event: \"log\", instanceId: ROOT, payload: { ...log, time: log.time.toISOString() } }));\n onServiceStateChange(payload => events.emit(\"event\", { type: \"event\", event: \"serviceState\", instanceId: ROOT, payload }));\n }\n return tasks;\n}\nexport function onManagementEvent(callback: (event: ManagementEvent) => void) { events.on(\"event\", callback); return () => events.off(\"event\", callback); }\nfunction params(request: ManagementRequest): Record<string, unknown> {\n if (request.params === undefined) return {};\n if (!request.params || typeof request.params !== \"object\" || Array.isArray(request.params)) throw new Error(\"\u53C2\u6570\u5FC5\u987B\u4E3A\u5BF9\u8C61\");\n return request.params as Record<string, unknown>;\n}\nfunction string(value: unknown, label: string) { if (typeof value !== \"string\" || value.length > 2 * 1024 * 1024) throw new Error(`\u975E\u6CD5 ${label}`); return value; }\n/** \u89E3\u6790\u65E5\u5FD7\u67E5\u8BE2\u7528\u7684 ISO \u65F6\u95F4\u3002\u7F3A\u7701\u8FD4\u56DE undefined\u3002 */\nfunction timeBound(value: unknown, label: string): Date | undefined {\n if (value === undefined) return undefined;\n const date = new Date(string(value, label));\n if (Number.isNaN(date.getTime())) throw new Error(`\u975E\u6CD5 ${label}`);\n return date;\n}\nfunction service(value: unknown): ServiceName { if (!SERVICE_NAMES.includes(value as ServiceName)) throw new Error(\"\u672A\u77E5\u670D\u52A1\"); return value as ServiceName; }\nasync function rebuildModules() {\n const build = await cmdPackBuild([]); if (!build.ok) throw new Error(build.message);\n const deploy = await cmdPackDeploy([]); if (!deploy.ok) throw new Error(deploy.message);\n return { changed: true };\n}\n\n/** configs/db_config.json \u4E2D\u7BA1\u7406\u901A\u9053\u7528\u5230\u7684\u5B57\u6BB5 */\ntype DbConfig = { db_port?: number; http_auth?: string; dbDir?: string };\n/** \u8BFB\u53D6\u4E1A\u52A1\u5E93\u914D\u7F6E\u3002\u4F7F\u7528\u573A\u666F\uFF1Aplayers.list \u67E5\u5728\u7EBF\u5FEB\u7167\u4E0E\u7ED1\u5B9A\uFF0Cactivity.* \u5B9A\u4F4D\u4E1A\u52A1\u5E93\u6587\u4EF6\u3002 */\nfunction dbConfig(): DbConfig {\n return readJson<DbConfig>(path.join(ROOT, \"configs\", \"db_config.json\"), {});\n}\n/** \u4E1A\u52A1\u5E93 SQLite \u6587\u4EF6\u8DEF\u5F84\uFF08dbDir \u7F3A\u7701\u4E3A data/sfmc_data.db\uFF0C\u4E0E db-server \u4E00\u81F4\uFF09\u3002 */\nfunction businessDatabase(cfg: DbConfig = dbConfig()): string {\n return path.resolve(ROOT, typeof cfg.dbDir === \"string\" && cfg.dbDir.trim() ? cfg.dbDir : \"data/sfmc_data.db\");\n}\nasync function players() {\n const files = playerFiles(); const allowlist = readJson<unknown[]>(files.allowlist, []);\n const cfg = dbConfig();\n const database = businessDatabase(cfg);\n let data: { online?: { name: string }[]; updatedAt?: number } = {};\n try {\n const response = await fetch(`http://127.0.0.1:${cfg.db_port ?? 3001}/api/sfmc/status`, { headers: cfg.http_auth ? { authorization: `Bearer ${cfg.http_auth}` } : {}, signal: AbortSignal.timeout(5000) });\n if (response.ok) data = await response.json() as typeof data;\n } catch { /* \u672A\u8FDE\u63A5\u65F6\u4F7F\u7528\u672A\u77E5\u72B6\u6001 */ }\n const fresh = typeof data.updatedAt === \"number\" && Date.now() - data.updatedAt < 60_000;\n return { players: (data.online ?? []).map(row => ({ name: row.name, xuid: \"\", online: fresh ? true : null })), updatedAt: data.updatedAt ? new Date(data.updatedAt).toISOString() : \"\", fresh, allowlist, permissions: readJson<unknown[]>(files.permissions, []), sfmcPermissions: readJson<unknown[]>(files.sfmcPermissions, []), bindings: readQqBindings(database) };\n}\nasync function bdsUpdate(context: TaskContext, checkOnly = false) {\n context.phase(\"download\", checkOnly ? \"\u68C0\u67E5 BDS \u66F4\u65B0\" : \"\u66F4\u65B0 BDS\");\n const args = checkOnly ? [\"--check-only\", \"--no-notify\"] : [\"--no-start\", \"--no-notify\"];\n let output = \"\";\n await new Promise<void>((resolve, reject) => {\n const child = spawnService(\"update\", args, { stdio: \"pipe\", cwd: ROOT });\n for (const stream of [child.stdout, child.stderr]) stream?.on(\"data\", chunk => { output = (output + String(chunk)).slice(-64_000); });\n child.on(\"error\", reject); child.on(\"close\", code => code === 0 ? resolve() : reject(new Error(`BDS \u66F4\u65B0\u5931\u8D25 (${code})`)));\n });\n return { checked: checkOnly, updated: /SFMC_UPDATE_RESULT=deployed/.test(output), currentVersion: /CURRENT=([^\\r\\n]+)/.exec(output)?.[1] ?? \"unknown\", latestVersion: /LATEST=([^\\r\\n]+)/.exec(output)?.[1] ?? \"unknown\", result: /SFMC_UPDATE_RESULT=([^\\r\\n]+)/.exec(output)?.[1] ?? \"unknown\" };\n}\nexport async function dispatchManagement(request: ManagementRequest): Promise<unknown> {\n const p = params(request); const store = managementTasks();\n switch (request.method) {\n case \"handshake\": return { protocolVersion: MANAGEMENT_PROTOCOL_VERSION, platformVersion: platformVersion(), host: { os: process.platform === \"win32\" ? \"windows\" : process.platform, arch: process.arch, release: os.release() }, root: ROOT, capabilities: [\"services\", \"logs\", \"logs-range\", \"modules\", \"config\", \"packs\", \"players\", \"updates\", \"operations\", \"metrics\", \"manual-restart\", \"manual-backup\", \"pack-import-plan\", \"pack-icons\", \"pack-uninstall\", \"backup-delete\", \"pack-import-batch\", \"pack-version\", ...LOCAL_CAPABILITIES], daemonPid: process.pid, daemonStartedAt: new Date(Date.now() - process.uptime() * 1000).toISOString(), initialized: deploymentInitialized() };\n case \"events.subscribe\": return { subscribed: true };\n case \"services.list\": return { rows: await queryServicesRuntimeLocal() };\n case \"services.start\": case \"services.stop\": case \"services.restart\": {\n const requestedNames = p.name === \"all\" ? [...START_ORDER] : [service(p.name)];\n const reloadConfig = p.reloadConfig === true;\n if (reloadConfig && (p.name !== \"all\" || request.method !== \"services.restart\")) throw new Error(\"\u91CD\u65B0\u8BFB\u53D6\u914D\u7F6E\u9700\u8981\u91CD\u542F\u5168\u90E8\u670D\u52A1\");\n return store.submit(request.method, async context => {\n context.phase(\"execute\");\n const rows = await queryServicesRuntimeLocal();\n const names = p.runningOnly === true\n ? requestedNames.filter(name => rows.some(row => row.name === name && row.running))\n : requestedNames;\n if (rows.some(row => names.includes(row.name) && row.running && row.ownership === \"external\") && request.method !== \"services.start\") throw new Error(\"\u5916\u90E8\u8FDB\u7A0B\u65E0\u6CD5\u5B89\u5168\u505C\u6B62\uFF0C\u8BF7\u901A\u8FC7\u539F\u7BA1\u7406\u5668\u64CD\u4F5C\");\n if (request.method !== \"services.start\") for (const name of [...names].reverse()) await services[name].stop(false, false);\n if (reloadConfig) {\n const after = await queryServicesRuntimeLocal();\n if (after.some(row => requestedNames.includes(row.name) && row.running)) throw new Error(\"\u670D\u52A1\u672A\u5B8C\u5168\u9000\u51FA\uFF0C\u5DF2\u4E2D\u6B62\u914D\u7F6E\u5237\u65B0\");\n refreshServices();\n }\n if (request.method !== \"services.stop\") {\n if (!reloadConfig) {\n const after = await queryServicesRuntimeLocal();\n if (request.method === \"services.restart\" && after.some(row => names.includes(row.name) && row.running)) throw new Error(\"\u670D\u52A1\u672A\u5B8C\u5168\u9000\u51FA\uFF0C\u5DF2\u4E2D\u6B62\u91CD\u542F\");\n const stopped = names.filter(name => !after.some(row => row.name === name && row.running));\n if (stopped.length) refreshServices(stopped);\n }\n const outcomes = [];\n for (const name of names) outcomes.push({ name, ...(await services[name].start()) });\n await verifyRunning(outcomes.filter(row => row.status !== \"skipped\").map(row => row.name));\n return { outcomes };\n }\n return { stopped: names };\n });\n }\n case \"services.send\": {\n const name = service(p.name); const message = string(p.message, \"\u547D\u4EE4\");\n if (/[\\r\\n]/.test(message) || !message.trim()) throw new Error(\"\u4E00\u6B21\u53EA\u80FD\u53D1\u9001\u4E00\u884C\u547D\u4EE4\");\n const target = services[name]; if (!target.proc?.stdin || !target.running) throw new Error(\"\u670D\u52A1\u672A\u6258\u7BA1\u6216\u6CA1\u6709\u547D\u4EE4\u8F93\u5165\u901A\u9053\");\n return withMaintenanceLock(ROOT, async () => { target.proc!.stdin!.write(message + \"\\n\"); return { delivered: true }; });\n }\n case \"logs.tail\": {\n const since = timeBound(p.since, \"\u5F00\u59CB\u65F6\u95F4\");\n const until = timeBound(p.until, \"\u7ED3\u675F\u65F6\u95F4\");\n if (since && until && until < since) throw new Error(\"\u7ED3\u675F\u65F6\u95F4\u4E0D\u80FD\u65E9\u4E8E\u5F00\u59CB\u65F6\u95F4\");\n const limit = Math.min(LOG_TAIL_MAX, Math.max(1, Number(p.limit) || 1000));\n const ranged = Boolean(since || until);\n const entries = readDiskLogs({\n ...(ranged ? {} : { limit }),\n ...(since ? { since } : {}),\n ...(until ? { until } : {}),\n ...(Array.isArray(p.sources) ? { sources: p.sources.map(value => string(value, \"\u65E5\u5FD7\u6765\u6E90\")) } : {}),\n ...(Array.isArray(p.levels) ? { levels: p.levels as (\"info\" | \"warn\" | \"error\")[] } : {}),\n });\n const truncated = entries.length > limit;\n return { entries: (truncated ? entries.slice(entries.length - limit) : entries).map(log => ({ ...log, time: log.time.toISOString() })), ...(truncated ? { truncated: true } : {}) };\n }\n case \"logs.delete\": {\n const since = timeBound(p.since, \"\u5F00\u59CB\u65F6\u95F4\");\n const until = timeBound(p.until, \"\u7ED3\u675F\u65F6\u95F4\");\n if (!since || !until) throw new Error(\"\u5220\u9664\u65E5\u5FD7\u9700\u8981\u5F00\u59CB\u548C\u7ED3\u675F\u65F6\u95F4\");\n if (until < since) throw new Error(\"\u7ED3\u675F\u65F6\u95F4\u4E0D\u80FD\u65E9\u4E8E\u5F00\u59CB\u65F6\u95F4\");\n const source = p.source === undefined ? undefined : string(p.source, \"\u65E5\u5FD7\u6765\u6E90\");\n if (source !== undefined && (source.length > 128 || /[\\r\\n]/.test(source))) throw new Error(\"\u975E\u6CD5\u65E5\u5FD7\u6765\u6E90\");\n const text = p.text === undefined ? undefined : string(p.text, \"\u65E5\u5FD7\u6B63\u6587\");\n return deleteStoredLogs({ since, until, ...(source === undefined ? {} : { source }), ...(text === undefined ? {} : { text }) });\n }\n case \"operations.list\": return { operations: store.list().filter(row => !Array.isArray(p.statuses) || p.statuses.includes(row.status)).slice(0, Math.min(Number(p.limit) || 100, 200)) };\n case \"operations.get\": return { operation: store.get(string(p.operationId, \"\u4EFB\u52A1\u7F16\u53F7\")) };\n case \"modules.list\": return listModules();\n case \"modules.search\": return searchModules(typeof p.query === \"string\" ? p.query : \"\");\n case \"modules.install\": {\n const id = identifier(p.id);\n const linked = (await listModules()).modules.find(row => row.id === id || row.folder === id)?.linked;\n if (linked) throw new Error(\"\u4FDD\u7559\u672C\u5730\u94FE\u63A5\u6A21\u5757\uFF0C\u4E0D\u901A\u8FC7\u5305\u5B89\u88C5\u6216\u5378\u8F7D\u8986\u76D6\u5F00\u53D1\u76EE\u5F55\");\n const block = await moduleInstallBlock(id);\n if (block) throw new Error(block);\n return store.submit(request.method, async context => {\n context.phase(\"download\", \"\u4E0B\u8F7D\u5E76\u5B89\u88C5\u6A21\u5757\uFF0C\u670D\u52A1\u5668\u4FDD\u6301\u8FD0\u884C\");\n const args = [\"install\", id];\n if (typeof p.source === \"string\" && p.source) args.push(\"--from\", p.source);\n await runFetch(args);\n context.phase(\"execute\", \"\u91CD\u5EFA\u884C\u4E3A\u5305\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS\");\n return { ...(await rebuildModules()), restartRequired: true };\n });\n }\n case \"modules.uninstall\": case \"modules.toggle\": {\n const id = identifier(p.id);\n if (request.method !== \"modules.toggle\") {\n const linked = (await listModules()).modules.find(row => row.id === id || row.folder === id)?.linked;\n if (linked) throw new Error(\"\u4FDD\u7559\u672C\u5730\u94FE\u63A5\u6A21\u5757\uFF0C\u4E0D\u901A\u8FC7\u5305\u5B89\u88C5\u6216\u5378\u8F7D\u8986\u76D6\u5F00\u53D1\u76EE\u5F55\");\n }\n return store.submit(request.method, async context => {\n context.phase(\"execute\", \"\u66F4\u65B0\u6A21\u5757\u5E76\u91CD\u5EFA\u884C\u4E3A\u5305\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS\");\n if (request.method === \"modules.toggle\") {\n const result = await (p.enabled === true ? cmdModuleEnable([id]) : cmdModuleDisable([id])); if (!result.ok) throw new Error(result.message);\n } else {\n await runFetch([\"uninstall\", id]);\n }\n return { ...(await rebuildModules()), restartRequired: true };\n });\n }\n case \"config.list\": return { keys: [...configFiles().keys()] };\n case \"config.read\": return readDocument(string(p.key, \"\u914D\u7F6E\u540D\u79F0\"));\n case \"config.save\": {\n const key = string(p.key, \"\u914D\u7F6E\u540D\u79F0\"); const text = string(p.text, \"\u914D\u7F6E\u5185\u5BB9\"); const expected = string(p.revision, \"\u914D\u7F6E\u7248\u672C\");\n const document = readDocument(key); validateDocument(document, text);\n if (document.revision !== expected) throw Object.assign(new Error(\"\u914D\u7F6E\u5DF2\u53D8\u66F4\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\"), { code: \"conflict\" });\n return store.submit(request.method, async context => {\n context.phase(\"execute\", \"\u4FDD\u5B58\u914D\u7F6E\u6587\u4EF6\uFF0C\u4E0D\u91CD\u542F\u670D\u52A1\");\n saveDocument(key, expected, text);\n return { saved: true, revision: revision(text), restartRequired: true };\n });\n }\n case \"config.apply\": {\n const key = string(p.key, \"\u914D\u7F6E\u540D\u79F0\"); const text = string(p.text, \"\u914D\u7F6E\u5185\u5BB9\"); const expected = string(p.revision, \"\u914D\u7F6E\u7248\u672C\");\n const document = readDocument(key); validateDocument(document, text);\n if (document.revision !== expected) throw Object.assign(new Error(\"\u914D\u7F6E\u5DF2\u53D8\u66F4\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\"), { code: \"conflict\" });\n return store.submit(request.method, async context => {\n let saved = false;\n try { return await withStoppedServices(context, [...START_ORDER], async () => {\n saveDocument(key, expected, text); context.phase(\"apply\", \"\u6587\u4EF6\u5DF2\u4FDD\u5B58\uFF0C\u6B63\u5728\u5E94\u7528\u8FD0\u884C\u914D\u7F6E\");\n saved = true;\n refreshServices(); return { saved: true, revision: readDocument(key).revision, applied: true };\n }); } catch (error) { throw Object.assign(new Error(`${saved ? \"\u6587\u4EF6\u5DF2\u4FDD\u5B58\uFF0C\u8FD0\u884C\u65F6\u5E94\u7528\u5931\u8D25\" : \"\u914D\u7F6E\u672A\u4FDD\u5B58\"}: ${error instanceof Error ? error.message : String(error)}`), { code: \"io\", details: { saved, applied: false } }); }\n });\n }\n case \"packs.list\": return listPacks();\n case \"packs.icon\": return readPackIcon(identifier(p.id));\n case \"packs.import.plan\": return planPackImport(identifier(p.filename));\n case \"packs.import\": {\n const names = readImportFilenames(p);\n return store.submit(request.method, async context => {\n context.phase(\"execute\", names.length > 1 ? `\u5BFC\u5165 ${names.length} \u4E2A\u4E16\u754C\u5305\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS` : \"\u5BFC\u5165\u4E16\u754C\u5305\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS\");\n return importPacks(names, { force: p.force === true, ...(p.revision === undefined ? {} : { revision: string(p.revision, \"\u5BFC\u5165\u8BA1\u5212\u7248\u672C\") }) });\n });\n }\n case \"packs.toggle\": return store.submit(request.method, async context => {\n context.phase(\"execute\", \"\u4FDD\u5B58\u4E16\u754C\u5305\u72B6\u6001\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS\");\n return togglePack(identifier(p.id), p.enabled === true);\n });\n case \"packs.uninstall\": return store.submit(request.method, async context => {\n context.phase(\"execute\", \"\u5378\u8F7D\u4E16\u754C\u5305\u5E76\u79FB\u5165\u56DE\u6536\u7AD9\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS\");\n return uninstallPack(identifier(p.id));\n });\n case \"packs.version\": {\n const id = identifier(p.id);\n const version = p.version;\n return store.submit(request.method, async context => {\n context.phase(\"execute\", \"\u5199\u5165\u8D44\u6E90\u5305\u7248\u672C\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS\");\n return setPackVersion(id, version);\n });\n }\n case \"players.list\": return players();\n case \"metrics.read\": return readRuntimeMetrics(request.params);\n case \"activity.query\": return readActivityPage(businessDatabase(), parseActivityFilter(p), parseActivityPaging(p));\n case \"activity.stats\": return readActivityStats(businessDatabase(), parseActivityFilter(p));\n case \"players.apply\": return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], async () => savePlayerPermissions(string(p.kind, \"\u6743\u9650\u7C7B\u578B\"), p.entries)));\n case \"attachment.plan\": return attachmentPlan();\n case \"attachment.apply\": return store.submit(request.method, async context => {\n const plan = await attachmentPlan(false);\n if (p.targetVersion !== undefined && p.targetVersion !== plan.targetVersion) throw Object.assign(new Error(\"\u76EE\u6807\u7248\u672C\u5DF2\u53D8\u66F4\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u66F4\u65B0\u65E5\u5FD7\u540E\u786E\u8BA4\"), { code: \"conflict\" });\n if (plan.externalServices.length) throw new Error(\"\u65E0\u6CD5\u53EF\u9760\u8FC1\u79FB\u5916\u90E8\u8FDB\u7A0B\uFF1B\u8BF7\u5148\u901A\u8FC7\u539F\u7BA1\u7406\u5668\u4F18\u96C5\u505C\u670D\");\n if (plan.upgradeRequired) return launchPlatformUpdate(store, context, plan.targetVersion);\n return { attached: true, version: plan.currentVersion, development: plan.development };\n });\n case \"updates.check\": {\n const results = await Promise.allSettled([attachmentPlan(), modulePlan(), bdsUpdate({ id: \"check\", phase: () => {} }, true)]);\n return Object.fromEntries(results.map((result, index) => [[\"platform\", \"modules\", \"bds\"][index], result.status === \"fulfilled\" ? result.value : { error: String(result.reason) }]));\n }\n case \"updates.run\": {\n if (p.kind === \"platform\") return store.submit(request.method, async context => { const plan = await attachmentPlan(false); if (p.targetVersion !== undefined && p.targetVersion !== plan.targetVersion) throw Object.assign(new Error(\"\u76EE\u6807\u7248\u672C\u5DF2\u53D8\u66F4\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u66F4\u65B0\u65E5\u5FD7\u540E\u786E\u8BA4\"), { code: \"conflict\" }); return plan.upgradeRequired ? launchPlatformUpdate(store, context, plan.targetVersion) : { upToDate: true, version: plan.currentVersion }; });\n if (p.kind === \"modules\") return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], async () => { const result = await applyModulePlan(Array.isArray(p.ids) ? p.ids.map(identifier) : []); await rebuildModules(); return result; }));\n if (p.kind === \"bds\") return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], () => bdsUpdate(context)));\n throw new Error(\"\u672A\u77E5\u66F4\u65B0\u7C7B\u578B\");\n }\n case \"deployment.create\": {\n if (p.acceptEula !== true) throw new Error(\"\u521B\u5EFA\u90E8\u7F72\u524D\u5FC5\u987B\u786E\u8BA4 BDS \u4F7F\u7528\u6761\u6B3E\");\n return store.submit(request.method, async context => {\n if (isRuntimeInitialized()) throw new Error(\"\u76EE\u5F55\u5DF2\u7ECF\u521D\u59CB\u5316\uFF0C\u4E0D\u8986\u76D6\u5DF2\u6709\u90E8\u7F72\");\n const ports = { db: deploymentPort(p.dbPort, 3001), bds: deploymentPort(p.bdsPort, 19132), bds6: deploymentPort(p.bdsPort6, 19133) };\n context.phase(\"preflight\", \"\u68C0\u67E5\u76EE\u5F55\u3001\u78C1\u76D8\u7A7A\u95F4\u548C TCP\uFF0FUDP \u7AEF\u53E3\"); await deploymentPreflight(ports);\n context.phase(\"prepare\"); ensureCoreConfigs(ROOT, [\"db_config\", \"qq_config\", \"bds_updater\", \"permissions\", \"qq_link\"]);\n const updater = path.join(ROOT, \"configs\", \"bds_updater.json\");\n atomicJson(updater, { ...readJson(updater, {}), bds_path: \"BDS\", backup_dir: \"backups\" });\n const dbFile = path.join(ROOT, \"configs\", \"db_config.json\"); atomicJson(dbFile, { ...readJson(dbFile, {}), db_port: ports.db });\n fs.mkdirSync(path.join(ROOT, \"modules\", \"packages\"), { recursive: true });\n await bdsUpdate(context);\n const properties = path.join(ROOT, \"BDS\", \"server.properties\");\n let text = fs.readFileSync(properties, \"utf8\");\n for (const [key, port] of [[\"server-port\", ports.bds], [\"server-portv6\", ports.bds6]] as const) text = text.replace(new RegExp(`^${key}=.*$`, \"m\"), `${key}=${port}`);\n fs.writeFileSync(properties, text);\n await rebuildModules();\n refreshServices(); context.phase(\"start\");\n const started: ServiceName[] = [];\n try { for (const name of START_ORDER) { const result = await services[name].start(); if (result.status !== \"skipped\") started.push(name); } await verifyRunning(started); }\n catch (error) { for (const name of [...START_ORDER].reverse()) await services[name].stop(false, false).catch(() => {}); throw error; }\n atomicJson(path.join(ROOT, \"configs\", \"runtime.json\"), { ...readJson(path.join(ROOT, \"configs\", \"runtime.json\"), {}), initialized_at: new Date().toISOString() });\n return { created: true, rows: await queryServicesRuntimeLocal() };\n });\n }\n case \"backups.list\": { const directory = path.join(ROOT, \".sfmc\", \"backups\"); return { backups: fs.existsSync(directory) ? fs.readdirSync(directory).filter(id => fs.existsSync(path.join(directory, id, \"manifest.json\"))) : [] }; }\n case \"backups.create\": return store.submit(request.method, context => createBackup(context));\n case \"backups.restore\": {\n if (p.confirmDataLoss !== true) throw new Error(\"\u6062\u590D\u6570\u636E\u9700\u8981\u660E\u786E\u786E\u8BA4\u4E22\u5F03\u5907\u4EFD\u4E4B\u540E\u7684\u53D8\u66F4\");\n return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], () => restoreSnapshot(identifier(p.id), context.phase)));\n }\n case \"backups.delete\": return store.submit(request.method, async context => {\n context.phase(\"execute\", \"\u5220\u9664\u5907\u4EFD\u76EE\u5F55\");\n return deleteSnapshot(identifier(p.id));\n });\n case \"startup.plan\": return startupPlan();\n default: throw Object.assign(new Error(`\u4E0D\u652F\u6301\u7684\u7BA1\u7406\u65B9\u6CD5: ${request.method}`), { code: \"unsupported\" });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../src/management/stdio.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../src/management/stdio.ts"],"names":[],"mappings":"AAiBA,uCAAuC;AACvC,wBAAsB,kBAAkB,kBA+EvC"}
|
package/dist/management/stdio.js
CHANGED
|
@@ -2,6 +2,13 @@ import readline from "node:readline";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import { toManagementError } from "@sfmc-bds/management";
|
|
5
|
+
import { LOCAL_CAPABILITIES, LOCAL_METHODS } from "./local-methods.js";
|
|
6
|
+
function withLocalCapabilities(response) {
|
|
7
|
+
const result = response.result;
|
|
8
|
+
if (!response.ok || !result || !Array.isArray(result.capabilities)) return response;
|
|
9
|
+
const capabilities = [.../* @__PURE__ */ new Set([...result.capabilities, ...LOCAL_CAPABILITIES])];
|
|
10
|
+
return { ...response, result: { ...result, capabilities } };
|
|
11
|
+
}
|
|
5
12
|
async function runManagementStdio() {
|
|
6
13
|
const output = process.stdout.write.bind(process.stdout);
|
|
7
14
|
for (const key of ["log", "info", "warn", "error", "debug"]) console[key] = (...args) => {
|
|
@@ -35,7 +42,7 @@ async function runManagementStdio() {
|
|
|
35
42
|
output(JSON.stringify({ type: "res", id: request.id, ok: true, result: await metrics.readRuntimeMetrics(request.params) }) + "\n");
|
|
36
43
|
return;
|
|
37
44
|
}
|
|
38
|
-
if (ready && request.method
|
|
45
|
+
if (ready && LOCAL_METHODS.has(request.method)) {
|
|
39
46
|
const backend2 = await import("./server.js");
|
|
40
47
|
output(JSON.stringify({ type: "res", id: request.id, ok: true, result: await backend2.dispatchManagement(request) }) + "\n");
|
|
41
48
|
return;
|
|
@@ -45,7 +52,7 @@ async function runManagementStdio() {
|
|
|
45
52
|
const result = await client.callDaemon("management", { request });
|
|
46
53
|
if (result.kind !== "management") throw new Error("\u65E7\u5B88\u62A4\u8FDB\u7A0B\u6CA1\u6709\u7BA1\u7406\u5165\u53E3");
|
|
47
54
|
if (request.method === "events.subscribe" && result.response.ok && !dispose) dispose = await client.ensureDaemonSubscription();
|
|
48
|
-
output(JSON.stringify(result.response) + "\n");
|
|
55
|
+
output(JSON.stringify(request.method === "handshake" ? withLocalCapabilities(result.response) : result.response) + "\n");
|
|
49
56
|
return;
|
|
50
57
|
} catch (error) {
|
|
51
58
|
if (request.method !== "handshake" || !/unknown method|管理入口/.test(error instanceof Error ? error.message : String(error))) throw error;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/management/stdio.ts"],
|
|
4
|
-
"sourcesContent": ["import readline from \"node:readline\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport { toManagementError, type ManagementRequest } from \"@sfmc-bds/management\";\n\n/** \u9996\u5E27\u786E\u5B9A\u5B9E\u4F8B\u76EE\u5F55\uFF0C\u4E4B\u540E\u624D\u52A0\u8F7D\u542B ROOT \u5355\u4F8B\u7684 CLI \u4EE3\u7801\u3002 */\nexport async function runManagementStdio() {\n const output = process.stdout.write.bind(process.stdout);\n for (const key of [\"log\", \"info\", \"warn\", \"error\", \"debug\"] as const) console[key] = (...args: unknown[]) => { process.stderr.write(args.map(value => typeof value === \"string\" ? value : JSON.stringify(value)).join(\" \") + \"\\n\"); };\n const lines = readline.createInterface({ input: process.stdin, crlfDelay: Infinity });\n let ready = false;\n let dispose: (() => void) | undefined;\n let forwarding: (() => void) | undefined;\n let legacy = false;\n const pending = new Set<Promise<void>>();\n const processLine = async (line: string) => {\n let request: ManagementRequest = { id: \"invalid\", method: \"invalid\" };\n try {\n if (Buffer.byteLength(line) > 4 * 1024 * 1024) throw new Error(\"\u7BA1\u7406\u5E27\u8FC7\u5927\");\n request = JSON.parse(line) as ManagementRequest;\n if (!request || typeof request.id !== \"string\" || request.id.length > 128 || typeof request.method !== \"string\" || request.method.length > 128) throw new Error(\"\u975E\u6CD5\u7BA1\u7406\u5E27\");\n if (!ready) {\n if (request.method !== \"handshake\") throw new Error(\"\u9996\u4E2A\u8BF7\u6C42\u5FC5\u987B\u4E3A\u63E1\u624B\");\n const params = request.params as { root?: unknown } | undefined;\n if (typeof params?.root !== \"string\" || !path.isAbsolute(params.root) || !fs.statSync(params.root).isDirectory()) throw new Error(\"\u9700\u8981\u6709\u6548\u7684\u5B9E\u4F8B\u7EDD\u5BF9\u76EE\u5F55\");\n process.env.SFMC_ROOT = path.resolve(params.root); ready = true;\n } else if (request.method === \"handshake\" && (request.params as { root?: string } | undefined)?.root && path.resolve((request.params as { root: string }).root) !== process.env.SFMC_ROOT) {\n throw new Error(\"\u4E00\u4E2A\u7BA1\u7406\u4F1A\u8BDD\u53EA\u80FD\u8FDE\u63A5\u4E00\u4E2A\u5B9E\u4F8B\");\n }\n const client = await import(\"../daemon/client.js\");\n if (!forwarding) forwarding = client.onDaemonManagementEvent(event => output(JSON.stringify(event) + \"\\n\"));\n // \u6307\u6807\u548C\u73A9\u5BB6\u540D\u5355\u8BFB\u5F53\u524D\u78C1\u76D8\u4E0A\u7684\u4EE3\u7801\u4E0E\u6570\u636E\u5E93\u3002\u7BA1\u7406\u901A\u9053\u6BCF\u6B21\u8FDE\u63A5\u90FD\u4F1A\u52A0\u8F7D\u65B0\u6587\u4EF6\uFF0C\u4E0D\u5FC5\u4E3A\u6B64\u91CD\u542F\u4ECD\u5728\u6258\u7BA1\u670D\u52A1\u7684\u5B88\u62A4\u8FDB\u7A0B\u3002\n if (ready && request.method === \"metrics.read\") {\n const metrics = await import(\"./metrics-read.js\");\n output(JSON.stringify({ type: \"res\", id: request.id, ok: true, result: await metrics.readRuntimeMetrics(request.params) }) + \"\\n\");\n return;\n }\n if (ready && request.method
|
|
5
|
-
"mappings": "AAAA,OAAO,cAAc;AACrB,OAAO,UAAU;AACjB,OAAO,QAAQ;AACf,SAAS,yBAAiD;
|
|
4
|
+
"sourcesContent": ["import readline from \"node:readline\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport { toManagementError, type ManagementRequest } from \"@sfmc-bds/management\";\nimport { LOCAL_CAPABILITIES, LOCAL_METHODS } from \"./local-methods.js\";\n\n/**\n * \u5B88\u62A4\u8FDB\u7A0B\u53EF\u80FD\u4ECD\u5728\u8FD0\u884C\u5347\u7EA7\u524D\u7684\u4EE3\u7801\uFF0C\u63E1\u624B\u7ED3\u679C\u91CC\u7F3A\u5C11\u672C\u5730\u65B9\u6CD5\u7684\u80FD\u529B\u3002\n * \u672C\u8FDB\u7A0B\u4F1A\u76F4\u63A5\u5904\u7406\u8FD9\u4E9B\u65B9\u6CD5\uFF0C\u6240\u4EE5\u628A\u80FD\u529B\u8865\u8FDB\u6210\u529F\u7684\u63E1\u624B\u54CD\u5E94\uFF1B\u5931\u8D25\u54CD\u5E94\u539F\u6837\u8FD4\u56DE\u3002\n */\nfunction withLocalCapabilities<T extends { ok: boolean; result?: unknown }>(response: T): T {\n const result = response.result as { capabilities?: unknown } | undefined;\n if (!response.ok || !result || !Array.isArray(result.capabilities)) return response;\n const capabilities = [...new Set([...(result.capabilities as string[]), ...LOCAL_CAPABILITIES])];\n return { ...response, result: { ...result, capabilities } };\n}\n\n/** \u9996\u5E27\u786E\u5B9A\u5B9E\u4F8B\u76EE\u5F55\uFF0C\u4E4B\u540E\u624D\u52A0\u8F7D\u542B ROOT \u5355\u4F8B\u7684 CLI \u4EE3\u7801\u3002 */\nexport async function runManagementStdio() {\n const output = process.stdout.write.bind(process.stdout);\n for (const key of [\"log\", \"info\", \"warn\", \"error\", \"debug\"] as const) console[key] = (...args: unknown[]) => { process.stderr.write(args.map(value => typeof value === \"string\" ? value : JSON.stringify(value)).join(\" \") + \"\\n\"); };\n const lines = readline.createInterface({ input: process.stdin, crlfDelay: Infinity });\n let ready = false;\n let dispose: (() => void) | undefined;\n let forwarding: (() => void) | undefined;\n let legacy = false;\n const pending = new Set<Promise<void>>();\n const processLine = async (line: string) => {\n let request: ManagementRequest = { id: \"invalid\", method: \"invalid\" };\n try {\n if (Buffer.byteLength(line) > 4 * 1024 * 1024) throw new Error(\"\u7BA1\u7406\u5E27\u8FC7\u5927\");\n request = JSON.parse(line) as ManagementRequest;\n if (!request || typeof request.id !== \"string\" || request.id.length > 128 || typeof request.method !== \"string\" || request.method.length > 128) throw new Error(\"\u975E\u6CD5\u7BA1\u7406\u5E27\");\n if (!ready) {\n if (request.method !== \"handshake\") throw new Error(\"\u9996\u4E2A\u8BF7\u6C42\u5FC5\u987B\u4E3A\u63E1\u624B\");\n const params = request.params as { root?: unknown } | undefined;\n if (typeof params?.root !== \"string\" || !path.isAbsolute(params.root) || !fs.statSync(params.root).isDirectory()) throw new Error(\"\u9700\u8981\u6709\u6548\u7684\u5B9E\u4F8B\u7EDD\u5BF9\u76EE\u5F55\");\n process.env.SFMC_ROOT = path.resolve(params.root); ready = true;\n } else if (request.method === \"handshake\" && (request.params as { root?: string } | undefined)?.root && path.resolve((request.params as { root: string }).root) !== process.env.SFMC_ROOT) {\n throw new Error(\"\u4E00\u4E2A\u7BA1\u7406\u4F1A\u8BDD\u53EA\u80FD\u8FDE\u63A5\u4E00\u4E2A\u5B9E\u4F8B\");\n }\n const client = await import(\"../daemon/client.js\");\n if (!forwarding) forwarding = client.onDaemonManagementEvent(event => output(JSON.stringify(event) + \"\\n\"));\n // \u6307\u6807\u548C\u73A9\u5BB6\u540D\u5355\u8BFB\u5F53\u524D\u78C1\u76D8\u4E0A\u7684\u4EE3\u7801\u4E0E\u6570\u636E\u5E93\u3002\u7BA1\u7406\u901A\u9053\u6BCF\u6B21\u8FDE\u63A5\u90FD\u4F1A\u52A0\u8F7D\u65B0\u6587\u4EF6\uFF0C\u4E0D\u5FC5\u4E3A\u6B64\u91CD\u542F\u4ECD\u5728\u6258\u7BA1\u670D\u52A1\u7684\u5B88\u62A4\u8FDB\u7A0B\u3002\n if (ready && request.method === \"metrics.read\") {\n const metrics = await import(\"./metrics-read.js\");\n output(JSON.stringify({ type: \"res\", id: request.id, ok: true, result: await metrics.readRuntimeMetrics(request.params) }) + \"\\n\");\n return;\n }\n if (ready && LOCAL_METHODS.has(request.method)) {\n const backend = await import(\"./server.js\");\n output(JSON.stringify({ type: \"res\", id: request.id, ok: true, result: await backend.dispatchManagement(request) }) + \"\\n\");\n return;\n }\n if (!legacy) {\n try {\n const result = await client.callDaemon(\"management\", { request });\n if (result.kind !== \"management\") throw new Error(\"\u65E7\u5B88\u62A4\u8FDB\u7A0B\u6CA1\u6709\u7BA1\u7406\u5165\u53E3\");\n if (request.method === \"events.subscribe\" && result.response.ok && !dispose) dispose = await client.ensureDaemonSubscription();\n output(JSON.stringify(request.method === \"handshake\" ? withLocalCapabilities(result.response) : result.response) + \"\\n\");\n return;\n } catch (error) {\n if (request.method !== \"handshake\" || !/unknown method|\u7BA1\u7406\u5165\u53E3/.test(error instanceof Error ? error.message : String(error))) throw error;\n legacy = true;\n try { process.env.SFMC_PLATFORM_VERSION = (JSON.parse(fs.readFileSync(path.join(process.env.SFMC_ROOT!, \"node_modules\", \"@sfmc-bds\", \"sfmc\", \"package.json\"), \"utf8\")) as { version: string }).version; } catch { process.env.SFMC_PLATFORM_VERSION = \"unknown\"; }\n }\n }\n // \u65E7\u90E8\u7F72\u53EA\u5F00\u653E\u63A5\u5165\u89C4\u5212\u3001\u72B6\u6001\u548C\u6301\u4E45\u5316\u4EFB\u52A1\uFF1B\u5347\u7EA7\u4EA4\u7ED9\u72EC\u7ACB\u7EF4\u62A4\u8FDB\u7A0B\u3002\n const backend = await import(\"./server.js\");\n let value: unknown;\n if (request.method === \"handshake\") {\n value = { ...(await backend.dispatchManagement(request) as object), capabilities: [\"services\", \"logs\", \"operations\", \"updates\"], legacy: true };\n } else if (request.method === \"services.list\") {\n const result = await client.callDaemon(\"status\");\n if (result.kind !== \"status\") throw new Error(\"\u65E7\u90E8\u7F72\u65E0\u6CD5\u63D0\u4F9B\u670D\u52A1\u72B6\u6001\");\n value = { rows: result.rows };\n } else if (request.method === \"attachment.plan\" || request.method === \"attachment.apply\") {\n const status = await client.callDaemon(\"status\");\n if (status.kind !== \"status\") throw new Error(\"\u65E7\u90E8\u7F72\u65E0\u6CD5\u63D0\u4F9B\u670D\u52A1\u72B6\u6001\");\n const running = status.rows.filter(row => row.running).map(row => row.name);\n if (request.method === \"attachment.apply\" && running.length) throw Object.assign(new Error(\"\u65E7\u5B88\u62A4\u8FDB\u7A0B\u7F3A\u5C11\u53EF\u786E\u8BA4\u7684\u4F18\u96C5\u7EF4\u62A4\u63A5\u53E3\uFF1B\u8BF7\u5148\u901A\u8FC7\u539F\u7BA1\u7406\u5668\u505C\u6B62\u670D\u52A1\uFF0C\u518D\u6267\u884C\u63A5\u5165\u5347\u7EA7\"), { code: \"conflict\" });\n const plan = await backend.dispatchManagement(request);\n value = request.method === \"attachment.plan\" ? { ...plan as object, externalServices: running } : plan;\n } else if ([\"events.subscribe\", \"logs.tail\", \"operations.list\", \"operations.get\", \"backups.list\"].includes(request.method)) value = await backend.dispatchManagement(request);\n else throw Object.assign(new Error(\"\u65E7\u90E8\u7F72\u9700\u5148\u901A\u8FC7\u63A5\u5165\u6D41\u7A0B\u5347\u7EA7\u5E73\u53F0\uFF0C\u518D\u4F7F\u7528\u5B8C\u6574\u7BA1\u7406\u529F\u80FD\"), { code: \"unsupported\" });\n output(JSON.stringify({ type: \"res\", id: request.id, ok: true, result: value }) + \"\\n\");\n } catch (error) { output(JSON.stringify({ type: \"res\", id: request?.id ?? \"invalid\", ok: false, error: toManagementError(error) }) + \"\\n\"); }\n };\n lines.on(\"line\", line => {\n if (pending.size >= 64) { process.stderr.write(\"\u7BA1\u7406\u8BF7\u6C42\u79EF\u538B\uFF0C\u5173\u95ED\u5F53\u524D\u4F1A\u8BDD\\n\"); lines.close(); return; }\n const action = processLine(line).catch(error => { process.stderr.write(String(error) + \"\\n\"); });\n pending.add(action); void action.finally(() => pending.delete(action));\n });\n // \u6807\u51C6\u8F93\u5165\u5173\u95ED\u8868\u793A\u7BA1\u7406\u7AEF\u79BB\u5F00\u3002\u53EA\u65AD\u5F00\u4E0E\u5B88\u62A4\u8FDB\u7A0B\u7684\u7BA1\u9053\uFF0C\u4E0D\u505C\u6B62\u670D\u52A1\u3002\n await new Promise<void>(resolve => lines.once(\"close\", resolve));\n await Promise.allSettled(pending); dispose?.(); forwarding?.();\n if (ready) (await import(\"../daemon/client.js\")).disconnectDaemonClient();\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["backend"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-sidecars.d.ts","sourceRoot":"","sources":["../src/module-sidecars.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"module-sidecars.d.ts","sourceRoot":"","sources":["../src/module-sidecars.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyHH;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,QAAQ,KAAK,IAAI,GACvD,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAUzC"}
|
package/dist/module-sidecars.js
CHANGED
|
@@ -3,6 +3,25 @@ import fs from "node:fs";
|
|
|
3
3
|
import net from "node:net";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
const children = /* @__PURE__ */ new Map();
|
|
6
|
+
let runtimeRoot = "";
|
|
7
|
+
function persistSidecars() {
|
|
8
|
+
if (!runtimeRoot) return;
|
|
9
|
+
const file = path.join(runtimeRoot, ".sfmc", "sidecars.runtime.json");
|
|
10
|
+
const processes = [...children.entries()].flatMap(([id, child]) => {
|
|
11
|
+
const pid = child.pid ?? 0;
|
|
12
|
+
if (!pid || child.exitCode !== null) return [];
|
|
13
|
+
return [{ id, pid }];
|
|
14
|
+
});
|
|
15
|
+
try {
|
|
16
|
+
if (!processes.length) {
|
|
17
|
+
fs.unlinkSync(file);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
21
|
+
fs.writeFileSync(file, JSON.stringify({ processes }) + "\n");
|
|
22
|
+
} catch {
|
|
23
|
+
}
|
|
24
|
+
}
|
|
6
25
|
function readJson(file) {
|
|
7
26
|
try {
|
|
8
27
|
const parsed = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
@@ -70,6 +89,7 @@ function loadSpecs(root) {
|
|
|
70
89
|
return found;
|
|
71
90
|
}
|
|
72
91
|
async function startModuleSidecars(root, log) {
|
|
92
|
+
runtimeRoot = root;
|
|
73
93
|
for (const { spec, dir } of loadSpecs(root)) {
|
|
74
94
|
if (children.has(spec.id)) continue;
|
|
75
95
|
if (!isEnabled(root, spec)) continue;
|
|
@@ -93,11 +113,13 @@ async function startModuleSidecars(root, log) {
|
|
|
93
113
|
log(`[${spec.id}] \u5DF2\u968F\u670D\u52A1\u5668\u542F\u52A8\u9644\u5C5E\u8FDB\u7A0B (PID ${child.pid ?? 0})`, "stdout");
|
|
94
114
|
child.on("exit", (code) => {
|
|
95
115
|
if (children.get(spec.id) === child) children.delete(spec.id);
|
|
116
|
+
persistSidecars();
|
|
96
117
|
log(`[${spec.id}] \u9644\u5C5E\u8FDB\u7A0B\u9000\u51FA (code ${code ?? "?"})`, code === 0 ? "stdout" : "stderr");
|
|
97
118
|
});
|
|
98
119
|
child.on("error", (err) => {
|
|
99
120
|
log(`[${spec.id}] \u9644\u5C5E\u8FDB\u7A0B\u542F\u52A8\u5931\u8D25: ${err.message}`, "stderr");
|
|
100
121
|
});
|
|
122
|
+
persistSidecars();
|
|
101
123
|
}
|
|
102
124
|
}
|
|
103
125
|
function stopModuleSidecars() {
|
|
@@ -108,6 +130,7 @@ function stopModuleSidecars() {
|
|
|
108
130
|
} catch {
|
|
109
131
|
}
|
|
110
132
|
}
|
|
133
|
+
persistSidecars();
|
|
111
134
|
}
|
|
112
135
|
export {
|
|
113
136
|
startModuleSidecars,
|