@sfmc-bds/cli 0.5.3 → 0.7.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/logs.d.ts +21 -0
- package/dist/logs.d.ts.map +1 -1
- package/dist/logs.js +67 -1
- package/dist/logs.js.map +2 -2
- package/dist/management/deployment.js +1 -1
- package/dist/management/deployment.js.map +2 -2
- package/dist/management/domain.d.ts +46 -2
- package/dist/management/domain.d.ts.map +1 -1
- package/dist/management/domain.js +112 -26
- package/dist/management/domain.js.map +2 -2
- package/dist/management/maintenance.d.ts +14 -1
- package/dist/management/maintenance.d.ts.map +1 -1
- package/dist/management/maintenance.js +46 -38
- package/dist/management/maintenance.js.map +2 -2
- package/dist/management/pack-import.d.ts +29 -0
- package/dist/management/pack-import.d.ts.map +1 -0
- package/dist/management/pack-import.js +108 -0
- package/dist/management/pack-import.js.map +7 -0
- package/dist/management/platform-worker.js +5 -6
- package/dist/management/platform-worker.js.map +2 -2
- package/dist/management/server.d.ts.map +1 -1
- package/dist/management/server.js +113 -33
- package/dist/management/server.js.map +2 -2
- package/dist/management/tasks.js +1 -1
- package/dist/management/tasks.js.map +2 -2
- package/dist/registry.d.ts +11 -5
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +35 -11
- package/dist/registry.js.map +2 -2
- package/dist/services.d.ts +2 -1
- package/dist/services.d.ts.map +1 -1
- package/dist/services.js +16 -3
- package/dist/services.js.map +2 -2
- package/dist/world-packs.d.ts +47 -0
- package/dist/world-packs.d.ts.map +1 -1
- package/dist/world-packs.js +38 -11
- package/dist/world-packs.js.map +2 -2
- package/package.json +6 -6
- package/scripts/module-install/lib/registry-index.mjs +50 -13
|
@@ -6,7 +6,7 @@ import { withMaintenanceLock } from "@sfmc-bds/management/node";
|
|
|
6
6
|
import { toManagementError } from "@sfmc-bds/management";
|
|
7
7
|
import { atomicJson } from "./tasks.js";
|
|
8
8
|
import { readJson, runProcess } from "./domain.js";
|
|
9
|
-
import {
|
|
9
|
+
import { runPnpm } from "./maintenance.js";
|
|
10
10
|
import { callDaemon, disconnectDaemonClient } from "../daemon/client.js";
|
|
11
11
|
import { ROOT } from "../runtime.js";
|
|
12
12
|
import { START_ORDER } from "../services.js";
|
|
@@ -125,7 +125,6 @@ async function main() {
|
|
|
125
125
|
const lock = readJson(path.join(ROOT, ".sfmc", "maintenance.lock"), { nonce: "" });
|
|
126
126
|
process.env.SFMC_MAINTENANCE_TOKEN = lock.nonce;
|
|
127
127
|
const daemon = await stopServices();
|
|
128
|
-
await createSnapshot(request.id, phase);
|
|
129
128
|
await exitDaemon(daemon);
|
|
130
129
|
phase("execute");
|
|
131
130
|
atomicJson(activeFile, { entry, version: request.target, pnpm: process.env.SFMC_PNPM_ENTRY });
|
|
@@ -144,7 +143,7 @@ async function main() {
|
|
|
144
143
|
await new Promise((resolve) => setTimeout(resolve, 3e3));
|
|
145
144
|
const status = await callDaemon("status");
|
|
146
145
|
if (status.kind !== "status" || request.running.some((name) => !status.rows.some((row) => row.name === name && row.running))) throw new Error("\u6B64\u524D\u8FD0\u884C\u7684\u670D\u52A1\u672A\u5168\u90E8\u6062\u590D");
|
|
147
|
-
record.result = { version: request.target
|
|
146
|
+
record.result = { version: request.target };
|
|
148
147
|
record.status = "succeeded";
|
|
149
148
|
} catch (error) {
|
|
150
149
|
let rolledBack = false;
|
|
@@ -154,10 +153,10 @@ async function main() {
|
|
|
154
153
|
atomicJson(activeFile, request.previous);
|
|
155
154
|
rolledBack = true;
|
|
156
155
|
} catch (rollbackError) {
|
|
157
|
-
phase("rollback-blocked", `\u65E0\u6CD5\u5B89\u5168\u505C\u6B62\u76EE\u6807\u7248\u672C\uFF1B\u4FDD\u7559\u5165\u53E3\
|
|
156
|
+
phase("rollback-blocked", `\u65E0\u6CD5\u5B89\u5168\u505C\u6B62\u76EE\u6807\u7248\u672C\uFF1B\u4FDD\u7559\u5F53\u524D\u5165\u53E3\uFF0C\u4E0D\u8986\u76D6\u73A9\u5BB6\u6570\u636E: ${String(rollbackError)}`);
|
|
158
157
|
}
|
|
159
158
|
}
|
|
160
|
-
record.result = { programRolledBack: rolledBack,
|
|
159
|
+
record.result = { programRolledBack: rolledBack, dataRestoreRequired: switched, preparedEntry };
|
|
161
160
|
throw error;
|
|
162
161
|
}
|
|
163
162
|
});
|
|
@@ -173,7 +172,7 @@ async function main() {
|
|
|
173
172
|
} catch (error) {
|
|
174
173
|
record.status = "failed";
|
|
175
174
|
record.error = toManagementError(error);
|
|
176
|
-
record.result ??= { programRolledBack: false,
|
|
175
|
+
record.result ??= { programRolledBack: false, dataRestoreRequired: switched, preparedEntry };
|
|
177
176
|
maintenanceLog(`failed ${record.error.message}`);
|
|
178
177
|
} finally {
|
|
179
178
|
record.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/management/platform-worker.ts"],
|
|
4
|
-
"sourcesContent": ["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport { pathToFileURL } from \"node:url\";\nimport { withMaintenanceLock } from \"@sfmc-bds/management/node\";\nimport { toManagementError, type OperationRecord } from \"@sfmc-bds/management\";\nimport { atomicJson } from \"./tasks.js\";\nimport { readJson, runProcess } from \"./domain.js\";\nimport { createSnapshot, runPnpm } from \"./maintenance.js\";\nimport { callDaemon, disconnectDaemonClient } from \"../daemon/client.js\";\nimport { ROOT } from \"../runtime.js\";\nimport { START_ORDER } from \"../services.js\";\nimport { daemonLogPath, readDaemonMeta } from \"../daemon/paths.js\";\n\n/**\n * \u7EF4\u62A4\u8FDB\u7A0B\u81EA\u5DF1\u5199\u65E5\u5FD7\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A\u7236\u8FDB\u7A0B\u628A\u6807\u51C6\u8F93\u51FA\u63A5\u5230\u81EA\u5DF1\u7684\u6587\u4EF6\u53E5\u67C4\u65F6\uFF0C\u5B88\u62A4\u8FDB\u7A0B\u9000\u51FA\u4F1A\u5BFC\u81F4\u8FD9\u6BB5\u8F93\u51FA\u4E22\u5931\uFF1B\u8FD9\u91CC\u76F4\u63A5\u8FFD\u52A0\u5230\u65E5\u5FD7\u6587\u4EF6\u3002\n */\nfunction maintenanceLog(message: string) {\n const file = process.env.SFMC_MAINTENANCE_LOG || path.join(ROOT, \".sfmc\", \"logs\", \"maintenance.log\");\n try {\n fs.mkdirSync(path.dirname(file), { recursive: true });\n fs.appendFileSync(file, `${new Date().toISOString()} ${message}\\n`);\n } catch { /* \u65E5\u5FD7\u5199\u5931\u8D25\u65F6\u4ECD\u4EE5\u4EFB\u52A1\u8BB0\u5F55\u4E3A\u51C6 */ }\n}\n\n/** \u672C\u8FDB\u7A0B\u5728\u72EC\u7ACB Node \u4E2D\u5E38\u9A7B\uFF0C\u5E73\u53F0\u6362\u5305\u4E0D\u4F1A\u5220\u9664\u5176\u5F53\u524D\u7248\u672C\u76EE\u5F55\u3002 */\nasync function main() {\n const requestFile = process.argv[2];\n if (!requestFile) throw new Error(\"\u7F3A\u5C11\u7EF4\u62A4\u4EFB\u52A1\u6587\u4EF6\");\n const request = readJson<{ id: string; target: string; running: string[]; previous: { entry: string } | null }>(requestFile, { id: \"\", target: \"\", running: [], previous: null });\n if (!/^[\\w-]+$/.test(request.id) || !/^\\d+\\.\\d+\\.\\d+$/.test(request.target)) throw new Error(\"\u975E\u6CD5\u7EF4\u62A4\u8BF7\u6C42\");\n const recordFile = path.join(ROOT, \".sfmc\", \"operations\", `${request.id}.json`);\n let record = readJson<OperationRecord>(recordFile, {} as OperationRecord);\n const phase = (name: string, message?: string) => {\n record = readJson<OperationRecord>(recordFile, record);\n const previous = record.phases.at(-1); if (previous?.status === \"running\") previous.status = \"done\";\n record.phases.push({ name, status: \"running\", ...(message ? { message } : {}) }); record.status = \"running\"; record.updatedAt = new Date().toISOString(); atomicJson(recordFile, record);\n maintenanceLog(`phase ${name}${message ? ` ${message}` : \"\"}`);\n };\n const runtime = path.join(ROOT, \".sfmc\", \"runtime\");\n const release = path.join(runtime, \"releases\", `${request.target}-${request.id}`);\n const activeFile = path.join(runtime, \"active.json\");\n let switched = false;\n let preparedEntry = \"\";\n /** \u65E7\u8FDB\u7A0B\u9000\u51FA\uFF0C\u4EE5\u53CA\u5B83\u7684\u65E5\u5FD7\u53E5\u67C4\u677E\u5F00\uFF0C\u5171\u7528\u8FD9\u4E00\u6BB5\u7B49\u5F85\u3002 */\n const daemonTeardownMs = 30_000;\n const waitExit = async (pid: number) => {\n const deadline = Date.now() + daemonTeardownMs;\n for (;;) {\n let alive = true; try { process.kill(pid, 0); } catch (error) { alive = (error as NodeJS.ErrnoException).code !== \"ESRCH\"; }\n if (!alive) return;\n if (Date.now() > deadline) throw new Error(\"\u5B88\u62A4\u8FDB\u7A0B\u5C1A\u672A\u9000\u51FA\uFF0C\u7981\u6B62\u5207\u6362\u5E73\u53F0\");\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n };\n /**\n * \u7B49\u5230 daemon.log \u53EF\u4EE5\u518D\u6B21\u8FFD\u52A0\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A\u5E73\u53F0\u6821\u9A8C\u4F1A\u62C9\u8D77\u4E0B\u4E00\u7248\u5B88\u62A4\u8FDB\u7A0B\uFF0C\u5B83\u4E00\u542F\u52A8\u5C31\u8FFD\u52A0\u8FD9\u4E2A\u6587\u4EF6\u3002\n * \u65E7\u65E5\u5FD7\u6CF5\u8981\u7B49 Node \u8FDB\u7A0B\u9000\u51FA\u540E\u624D\u5173\u95ED\u53E5\u67C4\uFF0C\u4E2D\u95F4\u4F1A\u8BA9\u6253\u5F00\u5931\u8D25\u3002\n */\n const waitDaemonLogAppendable = async () => {\n const log = daemonLogPath();\n const deadline = Date.now() + daemonTeardownMs;\n for (;;) {\n try {\n const fd = fs.openSync(log, \"a\");\n fs.closeSync(fd);\n return;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code !== \"EBUSY\") throw error;\n if (Date.now() > deadline) throw new Error(\"\u5B88\u62A4\u8FDB\u7A0B\u65E5\u5FD7\u4ECD\u88AB\u5360\u7528\uFF0C\u5DF2\u505C\u6B62\u5207\u6362\u5E73\u53F0\");\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n }\n };\n /** \u53EA\u505C\u670D\u52A1\uFF0C\u4E0D\u9000\u51FA\u5B88\u62A4\u8FDB\u7A0B\u3002\u5907\u4EFD\u5FC5\u987B\u53D1\u751F\u5728\u5B88\u62A4\u8FDB\u7A0B\u8FD8\u6D3B\u7740\u7684\u65F6\u5019\u3002 */\n const stopServices = async () => {\n const meta = readDaemonMeta();\n if (!meta) return meta;\n const status = await callDaemon(\"status\");\n if (status.kind !== \"status\") throw new Error(\"\u65E0\u6CD5\u786E\u8BA4\u5F53\u524D\u670D\u52A1\u72B6\u6001\");\n if (status.rows.some(row => row.running)) {\n const stopped = await callDaemon(\"maintenanceStop\");\n if (stopped.kind !== \"status\" || stopped.rows.some(row => row.running)) throw new Error(\"\u670D\u52A1\u6CA1\u6709\u4F18\u96C5\u9000\u51FA\");\n }\n return meta;\n };\n /** \u6587\u4EF6\u5907\u4EFD\u5B8C\u6210\u540E\u518D\u8BA9\u65E7\u5B88\u62A4\u8FDB\u7A0B\u9000\u51FA\uFF0C\u907F\u514D\u9000\u51FA\u65F6\u628A\u672C\u7EF4\u62A4\u8FDB\u7A0B\u4E00\u8D77\u5E26\u8D70\u3001\u5907\u4EFD\u505C\u5728\u534A\u622A\u3002 */\n const exitDaemon = async (meta: { pid: number } | null) => {\n if (!meta) return;\n await callDaemon(\"shutdown\"); disconnectDaemonClient(); await waitExit(meta.pid);\n };\n const shutdown = async () => { await exitDaemon(await stopServices()); };\n try {\n // \u63D0\u4EA4\u8FDB\u7A0B\u4FDD\u5B58 workerPid \u540E\u624D\u91CA\u653E\u9501\uFF1B\u7B49\u5F85\u63A5\u7BA1\uFF0C\u7981\u6B62\u7ADE\u6001\u8986\u76D6\u8BB0\u5F55\u3002\n await new Promise(resolve => setTimeout(resolve, 500));\n let acquired = false;\n for (let attempt = 0; attempt < 100 && !acquired; attempt++) {\n try {\n await withMaintenanceLock(ROOT, async () => {\n acquired = true;\n try {\n phase(\"prepare\", `\u51C6\u5907\u5E73\u53F0 ${request.target}`);\n fs.mkdirSync(release, { recursive: true });\n atomicJson(path.join(release, \"package.json\"), { private: true, dependencies: {} });\n await runPnpm([\"add\", \"--ignore-workspace\", \"--prod\", \"--ignore-scripts\", \"--save-exact\", `@sfmc-bds/sfmc@${request.target}`], release);\n const linked = path.join(release, \"node_modules\", \"@sfmc-bds\", \"sfmc\", \"bin\", \"sfmc.mjs\");\n if (!fs.existsSync(linked)) throw new Error(\"\u5E73\u53F0\u5165\u53E3\u4E0D\u5B58\u5728\");\n // pnpm \u7684\u4F9D\u8D56\u94FE\u63A5\u5728\u771F\u5B9E\u5305\u76EE\u5F55\u65C1\u3002\u4ECE junction \u8DEF\u5F84 createRequire \u4F1A\u627E\u4E0D\u5230 @sfmc-bds/cli\u3002\n const entry = fs.realpathSync(linked);\n // \u53D1\u5E03\u7684\u5E73\u53F0\u5FC5\u987B\u5305\u542B\u672C\u6B21\u684C\u9762\u6240\u9700\u7BA1\u7406\u534F\u8BAE\u3002\n const resolver = createRequire(entry);\n const cli = path.join(path.dirname(resolver.resolve(\"@sfmc-bds/cli/package.json\")), \"dist\", \"management\", \"stdio.js\");\n if (!fs.existsSync(cli)) throw new Error(\"\u6700\u65B0\u5E73\u53F0\u5C1A\u672A\u53D1\u5E03\u7BA1\u7406\u5165\u53E3\uFF0C\u4FDD\u7559\u5F53\u524D\u90E8\u7F72\uFF1B\u8BF7\u5148\u5B8C\u6210\u5E73\u53F0\u53D1\u7248\");\n const targetSdk = readJson<{ version: string }>(resolver.resolve(\"@sfmc-bds/sdk/package.json\"), { version: \"\" }).version;\n const { satisfiesSdk } = await import(pathToFileURL(path.join(path.dirname(cli), \"../..\", \"scripts/module-install/lib/semver.mjs\")).href) as { satisfiesSdk: (version: string, range: string) => boolean };\n const modules = path.join(ROOT, \"modules\", \"packages\");\n if (fs.existsSync(modules)) for (const folder of fs.readdirSync(modules)) {\n const pkg = readJson<{ peerDependencies?: Record<string, string> }>(path.join(modules, folder, \"package.json\"), {});\n const manifest = readJson<{ sdk?: string }>(path.join(modules, folder, \"sapi\", \"manifest.json\"), {});\n const range = pkg.peerDependencies?.[\"@sfmc-bds/sdk\"] ?? manifest.sdk;\n if (range && !satisfiesSdk(targetSdk, range)) throw new Error(`\u6A21\u5757 ${folder} \u4E0E\u76EE\u6807 SDK ${targetSdk} \u4E0D\u517C\u5BB9 (${range})\uFF1B\u4FDD\u7559\u56FA\u5B9A\u7248\u672C\u53CA\u672C\u5730\u94FE\u63A5\uFF0C\u5DF2\u505C\u6B62\u5347\u7EA7`);\n }\n preparedEntry = entry;\n phase(\"stop-services\");\n const lock = readJson<{ nonce: string }>(path.join(ROOT, \".sfmc\", \"maintenance.lock\"), { nonce: \"\" });\n process.env.SFMC_MAINTENANCE_TOKEN = lock.nonce;\n const daemon = await stopServices();\n await createSnapshot(request.id, phase);\n await exitDaemon(daemon);\n phase(\"execute\"); atomicJson(activeFile, { entry, version: request.target, pnpm: process.env.SFMC_PNPM_ENTRY }); switched = true;\n const launcher = path.join(runtime, \"launcher.mjs\");\n fs.writeFileSync(launcher, \"import fs from 'node:fs'; import path from 'node:path'; import {pathToFileURL,fileURLToPath} from 'node:url'; const base=path.dirname(fileURLToPath(import.meta.url)); const active=JSON.parse(fs.readFileSync(path.join(base,'active.json'),'utf8')); process.env.SFMC_DAEMON_ENTRY=fileURLToPath(import.meta.url); process.env.SFMC_NODE_BINARY=process.execPath; if(active.pnpm) process.env.SFMC_PNPM_ENTRY=active.pnpm; await import(pathToFileURL(active.entry).href);\\n\");\n for (const key of Object.keys(process.env)) if (key.startsWith(\"SFMC_SERVICE_\") && key.endsWith(\"_ENTRY\") || [\"SFMC_FETCH_MODULE\", \"SFMC_PLATFORM_VERSION\"].includes(key)) delete process.env[key];\n process.env.SFMC_DAEMON_ENTRY = launcher;\n phase(\"verify\");\n await waitDaemonLogAppendable();\n await runProcess(process.execPath, [launcher, \"status\"], ROOT);\n const handshake = await callDaemon(\"management\", { request: { id: request.id, method: \"handshake\" } });\n if (handshake.kind !== \"management\" || !handshake.response.ok || (handshake.response.result as { platformVersion?: string }).platformVersion !== request.target) throw new Error(\"\u76EE\u6807\u5E73\u53F0\u63E1\u624B\u9A8C\u8BC1\u5931\u8D25\");\n phase(\"restore\");\n for (const service of START_ORDER.filter(name => request.running.includes(name))) await callDaemon(\"start\", { name: service });\n await new Promise(resolve => setTimeout(resolve, 3000));\n const status = await callDaemon(\"status\");\n if (status.kind !== \"status\" || request.running.some(name => !status.rows.some(row => row.name === name && row.running))) throw new Error(\"\u6B64\u524D\u8FD0\u884C\u7684\u670D\u52A1\u672A\u5168\u90E8\u6062\u590D\");\n record.result = { version: request.target, backupId: request.id }; record.status = \"succeeded\";\n } catch (error) {\n // \u56DE\u9000\u4E5F\u5FC5\u987B\u5728\u540C\u4E00\u628A\u9501\u5185\u5B8C\u6210\uFF0C\u9632\u6B62\u5176\u4ED6\u5BA2\u6237\u7AEF\u5728\u5165\u53E3\u5207\u6362\u671F\u95F4\u5199\u5165\u3002\n let rolledBack = false;\n if (switched && request.previous) {\n try { await shutdown(); atomicJson(activeFile, request.previous); rolledBack = true; }\n catch (rollbackError) { phase(\"rollback-blocked\", `\u65E0\u6CD5\u5B89\u5168\u505C\u6B62\u76EE\u6807\u7248\u672C\uFF1B\u4FDD\u7559\u5165\u53E3\u548C\u5907\u4EFD\uFF0C\u4E0D\u8986\u76D6\u73A9\u5BB6\u6570\u636E: ${String(rollbackError)}`); }\n }\n record.result = { programRolledBack: rolledBack, backupId: request.id, dataRestoreRequired: switched, preparedEntry };\n throw error;\n }\n });\n } catch (error) {\n if (!acquired && (error as { code?: string }).code === \"locked\") { await new Promise(resolve => setTimeout(resolve, 200)); continue; }\n throw error;\n }\n }\n if (!acquired) throw new Error(\"\u65E0\u6CD5\u63A5\u7BA1\u7EF4\u62A4\u9501\");\n } catch (error) {\n record.status = \"failed\"; record.error = toManagementError(error);\n record.result ??= { programRolledBack: false, backupId: request.id, dataRestoreRequired: switched, preparedEntry };\n maintenanceLog(`failed ${record.error.message}`);\n } finally {\n record.updatedAt = new Date().toISOString(); const last = record.phases.at(-1); if (last) last.status = record.status === \"succeeded\" ? \"done\" : \"failed\";\n atomicJson(recordFile, record);\n fs.rmSync(requestFile, { force: true });\n disconnectDaemonClient();\n }\n}\nvoid main().catch(error => { process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`); process.exitCode = 1; });\n"],
|
|
5
|
-
"mappings": "AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AACpC,SAAS,yBAA+C;AACxD,SAAS,kBAAkB;AAC3B,SAAS,UAAU,kBAAkB;AACrC,SAAS,
|
|
4
|
+
"sourcesContent": ["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport { pathToFileURL } from \"node:url\";\nimport { withMaintenanceLock } from \"@sfmc-bds/management/node\";\nimport { toManagementError, type OperationRecord } from \"@sfmc-bds/management\";\nimport { atomicJson } from \"./tasks.js\";\nimport { readJson, runProcess } from \"./domain.js\";\nimport { runPnpm } from \"./maintenance.js\";\nimport { callDaemon, disconnectDaemonClient } from \"../daemon/client.js\";\nimport { ROOT } from \"../runtime.js\";\nimport { START_ORDER } from \"../services.js\";\nimport { daemonLogPath, readDaemonMeta } from \"../daemon/paths.js\";\n\n/**\n * \u7EF4\u62A4\u8FDB\u7A0B\u81EA\u5DF1\u5199\u65E5\u5FD7\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A\u7236\u8FDB\u7A0B\u628A\u6807\u51C6\u8F93\u51FA\u63A5\u5230\u81EA\u5DF1\u7684\u6587\u4EF6\u53E5\u67C4\u65F6\uFF0C\u5B88\u62A4\u8FDB\u7A0B\u9000\u51FA\u4F1A\u5BFC\u81F4\u8FD9\u6BB5\u8F93\u51FA\u4E22\u5931\uFF1B\u8FD9\u91CC\u76F4\u63A5\u8FFD\u52A0\u5230\u65E5\u5FD7\u6587\u4EF6\u3002\n */\nfunction maintenanceLog(message: string) {\n const file = process.env.SFMC_MAINTENANCE_LOG || path.join(ROOT, \".sfmc\", \"logs\", \"maintenance.log\");\n try {\n fs.mkdirSync(path.dirname(file), { recursive: true });\n fs.appendFileSync(file, `${new Date().toISOString()} ${message}\\n`);\n } catch { /* \u65E5\u5FD7\u5199\u5931\u8D25\u65F6\u4ECD\u4EE5\u4EFB\u52A1\u8BB0\u5F55\u4E3A\u51C6 */ }\n}\n\n/** \u672C\u8FDB\u7A0B\u5728\u72EC\u7ACB Node \u4E2D\u5E38\u9A7B\uFF0C\u5E73\u53F0\u6362\u5305\u4E0D\u4F1A\u5220\u9664\u5176\u5F53\u524D\u7248\u672C\u76EE\u5F55\u3002 */\nasync function main() {\n const requestFile = process.argv[2];\n if (!requestFile) throw new Error(\"\u7F3A\u5C11\u7EF4\u62A4\u4EFB\u52A1\u6587\u4EF6\");\n const request = readJson<{ id: string; target: string; running: string[]; previous: { entry: string } | null }>(requestFile, { id: \"\", target: \"\", running: [], previous: null });\n if (!/^[\\w-]+$/.test(request.id) || !/^\\d+\\.\\d+\\.\\d+$/.test(request.target)) throw new Error(\"\u975E\u6CD5\u7EF4\u62A4\u8BF7\u6C42\");\n const recordFile = path.join(ROOT, \".sfmc\", \"operations\", `${request.id}.json`);\n let record = readJson<OperationRecord>(recordFile, {} as OperationRecord);\n const phase = (name: string, message?: string) => {\n record = readJson<OperationRecord>(recordFile, record);\n const previous = record.phases.at(-1); if (previous?.status === \"running\") previous.status = \"done\";\n record.phases.push({ name, status: \"running\", ...(message ? { message } : {}) }); record.status = \"running\"; record.updatedAt = new Date().toISOString(); atomicJson(recordFile, record);\n maintenanceLog(`phase ${name}${message ? ` ${message}` : \"\"}`);\n };\n const runtime = path.join(ROOT, \".sfmc\", \"runtime\");\n const release = path.join(runtime, \"releases\", `${request.target}-${request.id}`);\n const activeFile = path.join(runtime, \"active.json\");\n let switched = false;\n let preparedEntry = \"\";\n /** \u65E7\u8FDB\u7A0B\u9000\u51FA\uFF0C\u4EE5\u53CA\u5B83\u7684\u65E5\u5FD7\u53E5\u67C4\u677E\u5F00\uFF0C\u5171\u7528\u8FD9\u4E00\u6BB5\u7B49\u5F85\u3002 */\n const daemonTeardownMs = 30_000;\n const waitExit = async (pid: number) => {\n const deadline = Date.now() + daemonTeardownMs;\n for (;;) {\n let alive = true; try { process.kill(pid, 0); } catch (error) { alive = (error as NodeJS.ErrnoException).code !== \"ESRCH\"; }\n if (!alive) return;\n if (Date.now() > deadline) throw new Error(\"\u5B88\u62A4\u8FDB\u7A0B\u5C1A\u672A\u9000\u51FA\uFF0C\u7981\u6B62\u5207\u6362\u5E73\u53F0\");\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n };\n /**\n * \u7B49\u5230 daemon.log \u53EF\u4EE5\u518D\u6B21\u8FFD\u52A0\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A\u5E73\u53F0\u6821\u9A8C\u4F1A\u62C9\u8D77\u4E0B\u4E00\u7248\u5B88\u62A4\u8FDB\u7A0B\uFF0C\u5B83\u4E00\u542F\u52A8\u5C31\u8FFD\u52A0\u8FD9\u4E2A\u6587\u4EF6\u3002\n * \u65E7\u65E5\u5FD7\u6CF5\u8981\u7B49 Node \u8FDB\u7A0B\u9000\u51FA\u540E\u624D\u5173\u95ED\u53E5\u67C4\uFF0C\u4E2D\u95F4\u4F1A\u8BA9\u6253\u5F00\u5931\u8D25\u3002\n */\n const waitDaemonLogAppendable = async () => {\n const log = daemonLogPath();\n const deadline = Date.now() + daemonTeardownMs;\n for (;;) {\n try {\n const fd = fs.openSync(log, \"a\");\n fs.closeSync(fd);\n return;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code !== \"EBUSY\") throw error;\n if (Date.now() > deadline) throw new Error(\"\u5B88\u62A4\u8FDB\u7A0B\u65E5\u5FD7\u4ECD\u88AB\u5360\u7528\uFF0C\u5DF2\u505C\u6B62\u5207\u6362\u5E73\u53F0\");\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n }\n };\n /** \u786E\u8BA4\u670D\u52A1\u5168\u90E8\u505C\u6B62\u540E\uFF0C\u624D\u5141\u8BB8\u9000\u51FA\u5B88\u62A4\u8FDB\u7A0B\u5E76\u5207\u6362\u5E73\u53F0\u5165\u53E3\u3002 */\n const stopServices = async () => {\n const meta = readDaemonMeta();\n if (!meta) return meta;\n const status = await callDaemon(\"status\");\n if (status.kind !== \"status\") throw new Error(\"\u65E0\u6CD5\u786E\u8BA4\u5F53\u524D\u670D\u52A1\u72B6\u6001\");\n if (status.rows.some(row => row.running)) {\n const stopped = await callDaemon(\"maintenanceStop\");\n if (stopped.kind !== \"status\" || stopped.rows.some(row => row.running)) throw new Error(\"\u670D\u52A1\u6CA1\u6709\u4F18\u96C5\u9000\u51FA\");\n }\n return meta;\n };\n /** \u9000\u51FA\u65E7\u5B88\u62A4\u8FDB\u7A0B\u5E76\u7B49\u5F85\u5B83\u91CA\u653E\u65E5\u5FD7\u53E5\u67C4\u3002 */\n const exitDaemon = async (meta: { pid: number } | null) => {\n if (!meta) return;\n await callDaemon(\"shutdown\"); disconnectDaemonClient(); await waitExit(meta.pid);\n };\n const shutdown = async () => { await exitDaemon(await stopServices()); };\n try {\n // \u63D0\u4EA4\u8FDB\u7A0B\u4FDD\u5B58 workerPid \u540E\u624D\u91CA\u653E\u9501\uFF1B\u7B49\u5F85\u63A5\u7BA1\uFF0C\u7981\u6B62\u7ADE\u6001\u8986\u76D6\u8BB0\u5F55\u3002\n await new Promise(resolve => setTimeout(resolve, 500));\n let acquired = false;\n for (let attempt = 0; attempt < 100 && !acquired; attempt++) {\n try {\n await withMaintenanceLock(ROOT, async () => {\n acquired = true;\n try {\n phase(\"prepare\", `\u51C6\u5907\u5E73\u53F0 ${request.target}`);\n fs.mkdirSync(release, { recursive: true });\n atomicJson(path.join(release, \"package.json\"), { private: true, dependencies: {} });\n await runPnpm([\"add\", \"--ignore-workspace\", \"--prod\", \"--ignore-scripts\", \"--save-exact\", `@sfmc-bds/sfmc@${request.target}`], release);\n const linked = path.join(release, \"node_modules\", \"@sfmc-bds\", \"sfmc\", \"bin\", \"sfmc.mjs\");\n if (!fs.existsSync(linked)) throw new Error(\"\u5E73\u53F0\u5165\u53E3\u4E0D\u5B58\u5728\");\n // pnpm \u7684\u4F9D\u8D56\u94FE\u63A5\u5728\u771F\u5B9E\u5305\u76EE\u5F55\u65C1\u3002\u4ECE junction \u8DEF\u5F84 createRequire \u4F1A\u627E\u4E0D\u5230 @sfmc-bds/cli\u3002\n const entry = fs.realpathSync(linked);\n // \u53D1\u5E03\u7684\u5E73\u53F0\u5FC5\u987B\u5305\u542B\u672C\u6B21\u684C\u9762\u6240\u9700\u7BA1\u7406\u534F\u8BAE\u3002\n const resolver = createRequire(entry);\n const cli = path.join(path.dirname(resolver.resolve(\"@sfmc-bds/cli/package.json\")), \"dist\", \"management\", \"stdio.js\");\n if (!fs.existsSync(cli)) throw new Error(\"\u6700\u65B0\u5E73\u53F0\u5C1A\u672A\u53D1\u5E03\u7BA1\u7406\u5165\u53E3\uFF0C\u4FDD\u7559\u5F53\u524D\u90E8\u7F72\uFF1B\u8BF7\u5148\u5B8C\u6210\u5E73\u53F0\u53D1\u7248\");\n const targetSdk = readJson<{ version: string }>(resolver.resolve(\"@sfmc-bds/sdk/package.json\"), { version: \"\" }).version;\n const { satisfiesSdk } = await import(pathToFileURL(path.join(path.dirname(cli), \"../..\", \"scripts/module-install/lib/semver.mjs\")).href) as { satisfiesSdk: (version: string, range: string) => boolean };\n const modules = path.join(ROOT, \"modules\", \"packages\");\n if (fs.existsSync(modules)) for (const folder of fs.readdirSync(modules)) {\n const pkg = readJson<{ peerDependencies?: Record<string, string> }>(path.join(modules, folder, \"package.json\"), {});\n const manifest = readJson<{ sdk?: string }>(path.join(modules, folder, \"sapi\", \"manifest.json\"), {});\n const range = pkg.peerDependencies?.[\"@sfmc-bds/sdk\"] ?? manifest.sdk;\n if (range && !satisfiesSdk(targetSdk, range)) throw new Error(`\u6A21\u5757 ${folder} \u4E0E\u76EE\u6807 SDK ${targetSdk} \u4E0D\u517C\u5BB9 (${range})\uFF1B\u4FDD\u7559\u56FA\u5B9A\u7248\u672C\u53CA\u672C\u5730\u94FE\u63A5\uFF0C\u5DF2\u505C\u6B62\u5347\u7EA7`);\n }\n preparedEntry = entry;\n phase(\"stop-services\");\n const lock = readJson<{ nonce: string }>(path.join(ROOT, \".sfmc\", \"maintenance.lock\"), { nonce: \"\" });\n process.env.SFMC_MAINTENANCE_TOKEN = lock.nonce;\n const daemon = await stopServices();\n await exitDaemon(daemon);\n phase(\"execute\"); atomicJson(activeFile, { entry, version: request.target, pnpm: process.env.SFMC_PNPM_ENTRY }); switched = true;\n const launcher = path.join(runtime, \"launcher.mjs\");\n fs.writeFileSync(launcher, \"import fs from 'node:fs'; import path from 'node:path'; import {pathToFileURL,fileURLToPath} from 'node:url'; const base=path.dirname(fileURLToPath(import.meta.url)); const active=JSON.parse(fs.readFileSync(path.join(base,'active.json'),'utf8')); process.env.SFMC_DAEMON_ENTRY=fileURLToPath(import.meta.url); process.env.SFMC_NODE_BINARY=process.execPath; if(active.pnpm) process.env.SFMC_PNPM_ENTRY=active.pnpm; await import(pathToFileURL(active.entry).href);\\n\");\n for (const key of Object.keys(process.env)) if (key.startsWith(\"SFMC_SERVICE_\") && key.endsWith(\"_ENTRY\") || [\"SFMC_FETCH_MODULE\", \"SFMC_PLATFORM_VERSION\"].includes(key)) delete process.env[key];\n process.env.SFMC_DAEMON_ENTRY = launcher;\n phase(\"verify\");\n await waitDaemonLogAppendable();\n await runProcess(process.execPath, [launcher, \"status\"], ROOT);\n const handshake = await callDaemon(\"management\", { request: { id: request.id, method: \"handshake\" } });\n if (handshake.kind !== \"management\" || !handshake.response.ok || (handshake.response.result as { platformVersion?: string }).platformVersion !== request.target) throw new Error(\"\u76EE\u6807\u5E73\u53F0\u63E1\u624B\u9A8C\u8BC1\u5931\u8D25\");\n phase(\"restore\");\n for (const service of START_ORDER.filter(name => request.running.includes(name))) await callDaemon(\"start\", { name: service });\n await new Promise(resolve => setTimeout(resolve, 3000));\n const status = await callDaemon(\"status\");\n if (status.kind !== \"status\" || request.running.some(name => !status.rows.some(row => row.name === name && row.running))) throw new Error(\"\u6B64\u524D\u8FD0\u884C\u7684\u670D\u52A1\u672A\u5168\u90E8\u6062\u590D\");\n record.result = { version: request.target }; record.status = \"succeeded\";\n } catch (error) {\n // \u56DE\u9000\u4E5F\u5FC5\u987B\u5728\u540C\u4E00\u628A\u9501\u5185\u5B8C\u6210\uFF0C\u9632\u6B62\u5176\u4ED6\u5BA2\u6237\u7AEF\u5728\u5165\u53E3\u5207\u6362\u671F\u95F4\u5199\u5165\u3002\n let rolledBack = false;\n if (switched && request.previous) {\n try { await shutdown(); atomicJson(activeFile, request.previous); rolledBack = true; }\n catch (rollbackError) { phase(\"rollback-blocked\", `\u65E0\u6CD5\u5B89\u5168\u505C\u6B62\u76EE\u6807\u7248\u672C\uFF1B\u4FDD\u7559\u5F53\u524D\u5165\u53E3\uFF0C\u4E0D\u8986\u76D6\u73A9\u5BB6\u6570\u636E: ${String(rollbackError)}`); }\n }\n record.result = { programRolledBack: rolledBack, dataRestoreRequired: switched, preparedEntry };\n throw error;\n }\n });\n } catch (error) {\n if (!acquired && (error as { code?: string }).code === \"locked\") { await new Promise(resolve => setTimeout(resolve, 200)); continue; }\n throw error;\n }\n }\n if (!acquired) throw new Error(\"\u65E0\u6CD5\u63A5\u7BA1\u7EF4\u62A4\u9501\");\n } catch (error) {\n record.status = \"failed\"; record.error = toManagementError(error);\n record.result ??= { programRolledBack: false, dataRestoreRequired: switched, preparedEntry };\n maintenanceLog(`failed ${record.error.message}`);\n } finally {\n record.updatedAt = new Date().toISOString(); const last = record.phases.at(-1); if (last) last.status = record.status === \"succeeded\" ? \"done\" : \"failed\";\n atomicJson(recordFile, record);\n fs.rmSync(requestFile, { force: true });\n disconnectDaemonClient();\n }\n}\nvoid main().catch(error => { process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`); process.exitCode = 1; });\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AACpC,SAAS,yBAA+C;AACxD,SAAS,kBAAkB;AAC3B,SAAS,UAAU,kBAAkB;AACrC,SAAS,eAAe;AACxB,SAAS,YAAY,8BAA8B;AACnD,SAAS,YAAY;AACrB,SAAS,mBAAmB;AAC5B,SAAS,eAAe,sBAAsB;AAM9C,SAAS,eAAe,SAAiB;AACvC,QAAM,OAAO,QAAQ,IAAI,wBAAwB,KAAK,KAAK,MAAM,SAAS,QAAQ,iBAAiB;AACnG,MAAI;AACF,OAAG,UAAU,KAAK,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACpD,OAAG,eAAe,MAAM,IAAG,oBAAI,KAAK,GAAE,YAAY,CAAC,IAAI,OAAO;AAAA,CAAI;AAAA,EACpE,QAAQ;AAAA,EAAuB;AACjC;AAGA,eAAe,OAAO;AACpB,QAAM,cAAc,QAAQ,KAAK,CAAC;AAClC,MAAI,CAAC,YAAa,OAAM,IAAI,MAAM,kDAAU;AAC5C,QAAM,UAAU,SAAgG,aAAa,EAAE,IAAI,IAAI,QAAQ,IAAI,SAAS,CAAC,GAAG,UAAU,KAAK,CAAC;AAChL,MAAI,CAAC,WAAW,KAAK,QAAQ,EAAE,KAAK,CAAC,kBAAkB,KAAK,QAAQ,MAAM,EAAG,OAAM,IAAI,MAAM,sCAAQ;AACrG,QAAM,aAAa,KAAK,KAAK,MAAM,SAAS,cAAc,GAAG,QAAQ,EAAE,OAAO;AAC9E,MAAI,SAAS,SAA0B,YAAY,CAAC,CAAoB;AACxE,QAAM,QAAQ,CAAC,MAAc,YAAqB;AAChD,aAAS,SAA0B,YAAY,MAAM;AACrD,UAAM,WAAW,OAAO,OAAO,GAAG,EAAE;AAAG,QAAI,UAAU,WAAW,UAAW,UAAS,SAAS;AAC7F,WAAO,OAAO,KAAK,EAAE,MAAM,QAAQ,WAAW,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC,EAAG,CAAC;AAAG,WAAO,SAAS;AAAW,WAAO,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAG,eAAW,YAAY,MAAM;AACvL,mBAAe,SAAS,IAAI,GAAG,UAAU,IAAI,OAAO,KAAK,EAAE,EAAE;AAAA,EAC/D;AACA,QAAM,UAAU,KAAK,KAAK,MAAM,SAAS,SAAS;AAClD,QAAM,UAAU,KAAK,KAAK,SAAS,YAAY,GAAG,QAAQ,MAAM,IAAI,QAAQ,EAAE,EAAE;AAChF,QAAM,aAAa,KAAK,KAAK,SAAS,aAAa;AACnD,MAAI,WAAW;AACf,MAAI,gBAAgB;AAEpB,QAAM,mBAAmB;AACzB,QAAM,WAAW,OAAO,QAAgB;AACtC,UAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,eAAS;AACP,UAAI,QAAQ;AAAM,UAAI;AAAE,gBAAQ,KAAK,KAAK,CAAC;AAAA,MAAG,SAAS,OAAO;AAAE,gBAAS,MAAgC,SAAS;AAAA,MAAS;AAC3H,UAAI,CAAC,MAAO;AACZ,UAAI,KAAK,IAAI,IAAI,SAAU,OAAM,IAAI,MAAM,4FAAiB;AAC5D,YAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,GAAG,CAAC;AAAA,IACvD;AAAA,EACF;AAMA,QAAM,0BAA0B,YAAY;AAC1C,UAAM,MAAM,cAAc;AAC1B,UAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,eAAS;AACP,UAAI;AACF,cAAM,KAAK,GAAG,SAAS,KAAK,GAAG;AAC/B,WAAG,UAAU,EAAE;AACf;AAAA,MACF,SAAS,OAAO;AACd,cAAM,OAAQ,MAAgC;AAC9C,YAAI,SAAS,QAAS,OAAM;AAC5B,YAAI,KAAK,IAAI,IAAI,SAAU,OAAM,IAAI,MAAM,8GAAoB;AAC/D,cAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,GAAG,CAAC;AAAA,MACvD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAe,YAAY;AAC/B,UAAM,OAAO,eAAe;AAC5B,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,SAAS,MAAM,WAAW,QAAQ;AACxC,QAAI,OAAO,SAAS,SAAU,OAAM,IAAI,MAAM,8DAAY;AAC1D,QAAI,OAAO,KAAK,KAAK,SAAO,IAAI,OAAO,GAAG;AACxC,YAAM,UAAU,MAAM,WAAW,iBAAiB;AAClD,UAAI,QAAQ,SAAS,YAAY,QAAQ,KAAK,KAAK,SAAO,IAAI,OAAO,EAAG,OAAM,IAAI,MAAM,kDAAU;AAAA,IACpG;AACA,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,OAAO,SAAiC;AACzD,QAAI,CAAC,KAAM;AACX,UAAM,WAAW,UAAU;AAAG,2BAAuB;AAAG,UAAM,SAAS,KAAK,GAAG;AAAA,EACjF;AACA,QAAM,WAAW,YAAY;AAAE,UAAM,WAAW,MAAM,aAAa,CAAC;AAAA,EAAG;AACvE,MAAI;AAEF,UAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,GAAG,CAAC;AACrD,QAAI,WAAW;AACf,aAAS,UAAU,GAAG,UAAU,OAAO,CAAC,UAAU,WAAW;AAC3D,UAAI;AACF,cAAM,oBAAoB,MAAM,YAAY;AAC1C,qBAAW;AACX,cAAI;AACJ,kBAAM,WAAW,4BAAQ,QAAQ,MAAM,EAAE;AACzC,eAAG,UAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AACzC,uBAAW,KAAK,KAAK,SAAS,cAAc,GAAG,EAAE,SAAS,MAAM,cAAc,CAAC,EAAE,CAAC;AAClF,kBAAM,QAAQ,CAAC,OAAO,sBAAsB,UAAU,oBAAoB,gBAAgB,kBAAkB,QAAQ,MAAM,EAAE,GAAG,OAAO;AACtI,kBAAM,SAAS,KAAK,KAAK,SAAS,gBAAgB,aAAa,QAAQ,OAAO,UAAU;AACxF,gBAAI,CAAC,GAAG,WAAW,MAAM,EAAG,OAAM,IAAI,MAAM,4CAAS;AAErD,kBAAM,QAAQ,GAAG,aAAa,MAAM;AAEpC,kBAAM,WAAW,cAAc,KAAK;AACpC,kBAAM,MAAM,KAAK,KAAK,KAAK,QAAQ,SAAS,QAAQ,4BAA4B,CAAC,GAAG,QAAQ,cAAc,UAAU;AACpH,gBAAI,CAAC,GAAG,WAAW,GAAG,EAAG,OAAM,IAAI,MAAM,0KAA8B;AACvE,kBAAM,YAAY,SAA8B,SAAS,QAAQ,4BAA4B,GAAG,EAAE,SAAS,GAAG,CAAC,EAAE;AACjH,kBAAM,EAAE,aAAa,IAAI,MAAM,OAAO,cAAc,KAAK,KAAK,KAAK,QAAQ,GAAG,GAAG,SAAS,uCAAuC,CAAC,EAAE;AACpI,kBAAM,UAAU,KAAK,KAAK,MAAM,WAAW,UAAU;AACrD,gBAAI,GAAG,WAAW,OAAO,EAAG,YAAW,UAAU,GAAG,YAAY,OAAO,GAAG;AACxE,oBAAM,MAAM,SAAwD,KAAK,KAAK,SAAS,QAAQ,cAAc,GAAG,CAAC,CAAC;AAClH,oBAAM,WAAW,SAA2B,KAAK,KAAK,SAAS,QAAQ,QAAQ,eAAe,GAAG,CAAC,CAAC;AACnG,oBAAM,QAAQ,IAAI,mBAAmB,eAAe,KAAK,SAAS;AAClE,kBAAI,SAAS,CAAC,aAAa,WAAW,KAAK,EAAG,OAAM,IAAI,MAAM,gBAAM,MAAM,2BAAY,SAAS,wBAAS,KAAK,+GAAqB;AAAA,YACpI;AACA,4BAAgB;AAChB,kBAAM,eAAe;AACrB,kBAAM,OAAO,SAA4B,KAAK,KAAK,MAAM,SAAS,kBAAkB,GAAG,EAAE,OAAO,GAAG,CAAC;AACpG,oBAAQ,IAAI,yBAAyB,KAAK;AAC1C,kBAAM,SAAS,MAAM,aAAa;AAClC,kBAAM,WAAW,MAAM;AACvB,kBAAM,SAAS;AAAG,uBAAW,YAAY,EAAE,OAAO,SAAS,QAAQ,QAAQ,MAAM,QAAQ,IAAI,gBAAgB,CAAC;AAAG,uBAAW;AAC5H,kBAAM,WAAW,KAAK,KAAK,SAAS,cAAc;AAClD,eAAG,cAAc,UAAU,gdAAgd;AAC3e,uBAAW,OAAO,OAAO,KAAK,QAAQ,GAAG,EAAG,KAAI,IAAI,WAAW,eAAe,KAAK,IAAI,SAAS,QAAQ,KAAK,CAAC,qBAAqB,uBAAuB,EAAE,SAAS,GAAG,EAAG,QAAO,QAAQ,IAAI,GAAG;AACjM,oBAAQ,IAAI,oBAAoB;AAChC,kBAAM,QAAQ;AACd,kBAAM,wBAAwB;AAC9B,kBAAM,WAAW,QAAQ,UAAU,CAAC,UAAU,QAAQ,GAAG,IAAI;AAC7D,kBAAM,YAAY,MAAM,WAAW,cAAc,EAAE,SAAS,EAAE,IAAI,QAAQ,IAAI,QAAQ,YAAY,EAAE,CAAC;AACrG,gBAAI,UAAU,SAAS,gBAAgB,CAAC,UAAU,SAAS,MAAO,UAAU,SAAS,OAAwC,oBAAoB,QAAQ,OAAQ,OAAM,IAAI,MAAM,8DAAY;AAC7L,kBAAM,SAAS;AACf,uBAAW,WAAW,YAAY,OAAO,UAAQ,QAAQ,QAAQ,SAAS,IAAI,CAAC,EAAG,OAAM,WAAW,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC7H,kBAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,GAAI,CAAC;AACtD,kBAAM,SAAS,MAAM,WAAW,QAAQ;AACxC,gBAAI,OAAO,SAAS,YAAY,QAAQ,QAAQ,KAAK,UAAQ,CAAC,OAAO,KAAK,KAAK,SAAO,IAAI,SAAS,QAAQ,IAAI,OAAO,CAAC,EAAG,OAAM,IAAI,MAAM,0EAAc;AACxJ,mBAAO,SAAS,EAAE,SAAS,QAAQ,OAAO;AAAG,mBAAO,SAAS;AAAA,UAC7D,SAAS,OAAO;AAEd,gBAAI,aAAa;AACjB,gBAAI,YAAY,QAAQ,UAAU;AAChC,kBAAI;AAAE,sBAAM,SAAS;AAAG,2BAAW,YAAY,QAAQ,QAAQ;AAAG,6BAAa;AAAA,cAAM,SAC9E,eAAe;AAAE,sBAAM,oBAAoB,2JAA8B,OAAO,aAAa,CAAC,EAAE;AAAA,cAAG;AAAA,YAC5G;AACA,mBAAO,SAAS,EAAE,mBAAmB,YAAY,qBAAqB,UAAU,cAAc;AAC9F,kBAAM;AAAA,UACR;AAAA,QACF,CAAC;AAAA,MACH,SAAS,OAAO;AACd,YAAI,CAAC,YAAa,MAA4B,SAAS,UAAU;AAAE,gBAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,GAAG,CAAC;AAAG;AAAA,QAAU;AACrI,cAAM;AAAA,MACR;AAAA,IACF;AACA,QAAI,CAAC,SAAU,OAAM,IAAI,MAAM,4CAAS;AAAA,EAC1C,SAAS,OAAO;AACd,WAAO,SAAS;AAAU,WAAO,QAAQ,kBAAkB,KAAK;AAChE,WAAO,WAAW,EAAE,mBAAmB,OAAO,qBAAqB,UAAU,cAAc;AAC3F,mBAAe,UAAU,OAAO,MAAM,OAAO,EAAE;AAAA,EACjD,UAAE;AACA,WAAO,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAG,UAAM,OAAO,OAAO,OAAO,GAAG,EAAE;AAAG,QAAI,KAAM,MAAK,SAAS,OAAO,WAAW,cAAc,SAAS;AACjJ,eAAW,YAAY,MAAM;AAC7B,OAAG,OAAO,aAAa,EAAE,OAAO,KAAK,CAAC;AACtC,2BAAuB;AAAA,EACzB;AACF;AACA,KAAK,KAAK,EAAE,MAAM,WAAS;AAAE,UAAQ,OAAO,MAAM,GAAG,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,CAAI;AAAG,UAAQ,WAAW;AAAG,CAAC;",
|
|
6
6
|
"names": []
|
|
7
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,
|
|
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;AAO/H,OAAO,EAAE,SAAS,EAAgC,MAAM,YAAY,CAAC;AAsBrE,wBAAgB,eAAe,cAQ9B;AACD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,2BAA+E;AA4C3J,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAuNrF"}
|
|
@@ -2,23 +2,24 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import os from "node:os";
|
|
4
4
|
import { EventEmitter } from "node:events";
|
|
5
|
-
import { MANAGEMENT_PROTOCOL_VERSION } from "@sfmc-bds/management";
|
|
5
|
+
import { LOG_TAIL_MAX, MANAGEMENT_PROTOCOL_VERSION } from "@sfmc-bds/management";
|
|
6
6
|
import { readQqBindings } from "@sfmc-bds/db-server/qq-bindings";
|
|
7
7
|
import { ROOT, isRuntimeInitialized, spawnService } from "../runtime.js";
|
|
8
8
|
import { queryServicesRuntimeLocal, services, START_ORDER, SERVICE_NAMES, refreshServices, onServiceStateChange } from "../services.js";
|
|
9
|
-
import { readDiskLogs, onLog } from "../logs.js";
|
|
9
|
+
import { readDiskLogs, deleteStoredLogs, onLog } from "../logs.js";
|
|
10
10
|
import { cmdModuleEnable, cmdModuleDisable } from "../module-commands.js";
|
|
11
11
|
import { ensureCoreConfigs } from "@sfmc-bds/sdk/node/config";
|
|
12
12
|
import { TaskStore, atomicJson } from "./tasks.js";
|
|
13
|
-
import { configFiles, readDocument, saveDocument, validateDocument } from "./config.js";
|
|
14
|
-
import { listModules, searchModules, identifier, runFetch, readJson, listPacks, togglePack,
|
|
15
|
-
import { attachmentPlan, platformVersion, withStoppedServices, launchPlatformUpdate, restoreSnapshot, verifyRunning } from "./maintenance.js";
|
|
13
|
+
import { configFiles, readDocument, revision, saveDocument, validateDocument } from "./config.js";
|
|
14
|
+
import { listModules, searchModules, identifier, runFetch, readJson, listPacks, togglePack, readPackIcon, uninstallPack, setPackVersion, playerFiles, savePlayerPermissions, modulePlan, applyModulePlan, moduleInstallBlock } from "./domain.js";
|
|
15
|
+
import { attachmentPlan, platformVersion, withStoppedServices, launchPlatformUpdate, createBackup, restoreSnapshot, deleteSnapshot, verifyRunning } from "./maintenance.js";
|
|
16
16
|
import { startupPlan } from "./startup.js";
|
|
17
17
|
import { cmdPackBuild, cmdPackDeploy } from "../pack-lifecycle.js";
|
|
18
18
|
import { withMaintenanceLock } from "@sfmc-bds/management/node";
|
|
19
19
|
import { deploymentPreflight, deploymentPort } from "./deployment.js";
|
|
20
20
|
import { resolveBdsContext } from "../pack-lifecycle.js";
|
|
21
21
|
import { readRuntimeMetrics } from "./metrics-read.js";
|
|
22
|
+
import { importPacks, planPackImport, readImportFilenames } from "./pack-import.js";
|
|
22
23
|
const events = new EventEmitter();
|
|
23
24
|
function deploymentInitialized() {
|
|
24
25
|
if (isRuntimeInitialized()) return true;
|
|
@@ -49,6 +50,12 @@ function string(value, label) {
|
|
|
49
50
|
if (typeof value !== "string" || value.length > 2 * 1024 * 1024) throw new Error(`\u975E\u6CD5 ${label}`);
|
|
50
51
|
return value;
|
|
51
52
|
}
|
|
53
|
+
function timeBound(value, label) {
|
|
54
|
+
if (value === void 0) return void 0;
|
|
55
|
+
const date = new Date(string(value, label));
|
|
56
|
+
if (Number.isNaN(date.getTime())) throw new Error(`\u975E\u6CD5 ${label}`);
|
|
57
|
+
return date;
|
|
58
|
+
}
|
|
52
59
|
function service(value) {
|
|
53
60
|
if (!SERVICE_NAMES.includes(value)) throw new Error("\u672A\u77E5\u670D\u52A1");
|
|
54
61
|
return value;
|
|
@@ -60,20 +67,6 @@ async function rebuildModules() {
|
|
|
60
67
|
if (!deploy.ok) throw new Error(deploy.message);
|
|
61
68
|
return { changed: true };
|
|
62
69
|
}
|
|
63
|
-
async function applyInstalledModule(phase) {
|
|
64
|
-
phase("execute", "\u91CD\u5EFA\u884C\u4E3A\u5305");
|
|
65
|
-
const rebuilt = await rebuildModules();
|
|
66
|
-
phase("reload", "\u5411\u8FD0\u884C\u4E2D\u7684 BDS \u53D1\u9001 reload\uFF0C\u4E0D\u505C\u6B62\u670D\u52A1\u5668");
|
|
67
|
-
await queryServicesRuntimeLocal();
|
|
68
|
-
const bds = services.bds;
|
|
69
|
-
if (!bds.running || !bds.proc?.stdin) return { ...rebuilt, reloaded: false };
|
|
70
|
-
try {
|
|
71
|
-
bds.proc.stdin.write("reload\n");
|
|
72
|
-
} catch (error) {
|
|
73
|
-
throw new Error(`\u6A21\u5757\u5DF2\u5B89\u88C5\uFF0C\u4F46\u70ED\u91CD\u8F7D\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
74
|
-
}
|
|
75
|
-
return { ...rebuilt, reloaded: true };
|
|
76
|
-
}
|
|
77
70
|
async function players() {
|
|
78
71
|
const files = playerFiles();
|
|
79
72
|
const allowlist = readJson(files.allowlist, []);
|
|
@@ -107,7 +100,7 @@ async function dispatchManagement(request) {
|
|
|
107
100
|
const store = managementTasks();
|
|
108
101
|
switch (request.method) {
|
|
109
102
|
case "handshake":
|
|
110
|
-
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", "modules", "config", "packs", "players", "updates", "operations", "metrics"], daemonPid: process.pid, daemonStartedAt: new Date(Date.now() - process.uptime() * 1e3).toISOString(), initialized: deploymentInitialized() };
|
|
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
104
|
case "events.subscribe":
|
|
112
105
|
return { subscribed: true };
|
|
113
106
|
case "services.list":
|
|
@@ -115,13 +108,27 @@ async function dispatchManagement(request) {
|
|
|
115
108
|
case "services.start":
|
|
116
109
|
case "services.stop":
|
|
117
110
|
case "services.restart": {
|
|
118
|
-
const
|
|
111
|
+
const requestedNames = p.name === "all" ? [...START_ORDER] : [service(p.name)];
|
|
112
|
+
const reloadConfig = p.reloadConfig === true;
|
|
113
|
+
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");
|
|
119
114
|
return store.submit(request.method, async (context) => {
|
|
120
115
|
context.phase("execute");
|
|
121
116
|
const rows = await queryServicesRuntimeLocal();
|
|
117
|
+
const names = p.runningOnly === true ? requestedNames.filter((name) => rows.some((row) => row.name === name && row.running)) : requestedNames;
|
|
122
118
|
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");
|
|
123
119
|
if (request.method !== "services.start") for (const name of [...names].reverse()) await services[name].stop(false, false);
|
|
120
|
+
if (reloadConfig) {
|
|
121
|
+
const after = await queryServicesRuntimeLocal();
|
|
122
|
+
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");
|
|
123
|
+
refreshServices();
|
|
124
|
+
}
|
|
124
125
|
if (request.method !== "services.stop") {
|
|
126
|
+
if (!reloadConfig) {
|
|
127
|
+
const after = await queryServicesRuntimeLocal();
|
|
128
|
+
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");
|
|
129
|
+
const stopped = names.filter((name) => !after.some((row) => row.name === name && row.running));
|
|
130
|
+
if (stopped.length) refreshServices(stopped);
|
|
131
|
+
}
|
|
125
132
|
const outcomes = [];
|
|
126
133
|
for (const name of names) outcomes.push({ name, ...await services[name].start() });
|
|
127
134
|
await verifyRunning(outcomes.filter((row) => row.status !== "skipped").map((row) => row.name));
|
|
@@ -141,8 +148,32 @@ async function dispatchManagement(request) {
|
|
|
141
148
|
return { delivered: true };
|
|
142
149
|
});
|
|
143
150
|
}
|
|
144
|
-
case "logs.tail":
|
|
145
|
-
|
|
151
|
+
case "logs.tail": {
|
|
152
|
+
const since = timeBound(p.since, "\u5F00\u59CB\u65F6\u95F4");
|
|
153
|
+
const until = timeBound(p.until, "\u7ED3\u675F\u65F6\u95F4");
|
|
154
|
+
if (since && until && until < since) throw new Error("\u7ED3\u675F\u65F6\u95F4\u4E0D\u80FD\u65E9\u4E8E\u5F00\u59CB\u65F6\u95F4");
|
|
155
|
+
const limit = Math.min(LOG_TAIL_MAX, Math.max(1, Number(p.limit) || 1e3));
|
|
156
|
+
const ranged = Boolean(since || until);
|
|
157
|
+
const entries = readDiskLogs({
|
|
158
|
+
...ranged ? {} : { limit },
|
|
159
|
+
...since ? { since } : {},
|
|
160
|
+
...until ? { until } : {},
|
|
161
|
+
...Array.isArray(p.sources) ? { sources: p.sources.map((value) => string(value, "\u65E5\u5FD7\u6765\u6E90")) } : {},
|
|
162
|
+
...Array.isArray(p.levels) ? { levels: p.levels } : {}
|
|
163
|
+
});
|
|
164
|
+
const truncated = entries.length > limit;
|
|
165
|
+
return { entries: (truncated ? entries.slice(entries.length - limit) : entries).map((log) => ({ ...log, time: log.time.toISOString() })), ...truncated ? { truncated: true } : {} };
|
|
166
|
+
}
|
|
167
|
+
case "logs.delete": {
|
|
168
|
+
const since = timeBound(p.since, "\u5F00\u59CB\u65F6\u95F4");
|
|
169
|
+
const until = timeBound(p.until, "\u7ED3\u675F\u65F6\u95F4");
|
|
170
|
+
if (!since || !until) throw new Error("\u5220\u9664\u65E5\u5FD7\u9700\u8981\u5F00\u59CB\u548C\u7ED3\u675F\u65F6\u95F4");
|
|
171
|
+
if (until < since) throw new Error("\u7ED3\u675F\u65F6\u95F4\u4E0D\u80FD\u65E9\u4E8E\u5F00\u59CB\u65F6\u95F4");
|
|
172
|
+
const source = p.source === void 0 ? void 0 : string(p.source, "\u65E5\u5FD7\u6765\u6E90");
|
|
173
|
+
if (source !== void 0 && (source.length > 128 || /[\r\n]/.test(source))) throw new Error("\u975E\u6CD5\u65E5\u5FD7\u6765\u6E90");
|
|
174
|
+
const text = p.text === void 0 ? void 0 : string(p.text, "\u65E5\u5FD7\u6B63\u6587");
|
|
175
|
+
return deleteStoredLogs({ since, until, ...source === void 0 ? {} : { source }, ...text === void 0 ? {} : { text } });
|
|
176
|
+
}
|
|
146
177
|
case "operations.list":
|
|
147
178
|
return { operations: store.list().filter((row) => !Array.isArray(p.statuses) || p.statuses.includes(row.status)).slice(0, Math.min(Number(p.limit) || 100, 200)) };
|
|
148
179
|
case "operations.get":
|
|
@@ -155,12 +186,15 @@ async function dispatchManagement(request) {
|
|
|
155
186
|
const id = identifier(p.id);
|
|
156
187
|
const linked = (await listModules()).modules.find((row) => row.id === id || row.folder === id)?.linked;
|
|
157
188
|
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");
|
|
189
|
+
const block = await moduleInstallBlock(id);
|
|
190
|
+
if (block) throw new Error(block);
|
|
158
191
|
return store.submit(request.method, async (context) => {
|
|
159
192
|
context.phase("download", "\u4E0B\u8F7D\u5E76\u5B89\u88C5\u6A21\u5757\uFF0C\u670D\u52A1\u5668\u4FDD\u6301\u8FD0\u884C");
|
|
160
193
|
const args = ["install", id];
|
|
161
194
|
if (typeof p.source === "string" && p.source) args.push("--from", p.source);
|
|
162
195
|
await runFetch(args);
|
|
163
|
-
|
|
196
|
+
context.phase("execute", "\u91CD\u5EFA\u884C\u4E3A\u5305\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS");
|
|
197
|
+
return { ...await rebuildModules(), restartRequired: true };
|
|
164
198
|
});
|
|
165
199
|
}
|
|
166
200
|
case "modules.uninstall":
|
|
@@ -170,20 +204,34 @@ async function dispatchManagement(request) {
|
|
|
170
204
|
const linked = (await listModules()).modules.find((row) => row.id === id || row.folder === id)?.linked;
|
|
171
205
|
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");
|
|
172
206
|
}
|
|
173
|
-
return store.submit(request.method,
|
|
207
|
+
return store.submit(request.method, async (context) => {
|
|
208
|
+
context.phase("execute", "\u66F4\u65B0\u6A21\u5757\u5E76\u91CD\u5EFA\u884C\u4E3A\u5305\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS");
|
|
174
209
|
if (request.method === "modules.toggle") {
|
|
175
210
|
const result = await (p.enabled === true ? cmdModuleEnable([id]) : cmdModuleDisable([id]));
|
|
176
211
|
if (!result.ok) throw new Error(result.message);
|
|
177
212
|
} else {
|
|
178
213
|
await runFetch(["uninstall", id]);
|
|
179
214
|
}
|
|
180
|
-
return rebuildModules();
|
|
181
|
-
}
|
|
215
|
+
return { ...await rebuildModules(), restartRequired: true };
|
|
216
|
+
});
|
|
182
217
|
}
|
|
183
218
|
case "config.list":
|
|
184
219
|
return { keys: [...configFiles().keys()] };
|
|
185
220
|
case "config.read":
|
|
186
221
|
return readDocument(string(p.key, "\u914D\u7F6E\u540D\u79F0"));
|
|
222
|
+
case "config.save": {
|
|
223
|
+
const key = string(p.key, "\u914D\u7F6E\u540D\u79F0");
|
|
224
|
+
const text = string(p.text, "\u914D\u7F6E\u5185\u5BB9");
|
|
225
|
+
const expected = string(p.revision, "\u914D\u7F6E\u7248\u672C");
|
|
226
|
+
const document = readDocument(key);
|
|
227
|
+
validateDocument(document, text);
|
|
228
|
+
if (document.revision !== expected) throw Object.assign(new Error("\u914D\u7F6E\u5DF2\u53D8\u66F4\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6"), { code: "conflict" });
|
|
229
|
+
return store.submit(request.method, async (context) => {
|
|
230
|
+
context.phase("execute", "\u4FDD\u5B58\u914D\u7F6E\u6587\u4EF6\uFF0C\u4E0D\u91CD\u542F\u670D\u52A1");
|
|
231
|
+
saveDocument(key, expected, text);
|
|
232
|
+
return { saved: true, revision: revision(text), restartRequired: true };
|
|
233
|
+
});
|
|
234
|
+
}
|
|
187
235
|
case "config.apply": {
|
|
188
236
|
const key = string(p.key, "\u914D\u7F6E\u540D\u79F0");
|
|
189
237
|
const text = string(p.text, "\u914D\u7F6E\u5185\u5BB9");
|
|
@@ -202,16 +250,41 @@ async function dispatchManagement(request) {
|
|
|
202
250
|
return { saved: true, revision: readDocument(key).revision, applied: true };
|
|
203
251
|
});
|
|
204
252
|
} catch (error) {
|
|
205
|
-
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
|
|
253
|
+
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 } });
|
|
206
254
|
}
|
|
207
255
|
});
|
|
208
256
|
}
|
|
209
257
|
case "packs.list":
|
|
210
258
|
return listPacks();
|
|
211
|
-
case "packs.
|
|
212
|
-
return
|
|
259
|
+
case "packs.icon":
|
|
260
|
+
return readPackIcon(identifier(p.id));
|
|
261
|
+
case "packs.import.plan":
|
|
262
|
+
return planPackImport(identifier(p.filename));
|
|
263
|
+
case "packs.import": {
|
|
264
|
+
const names = readImportFilenames(p);
|
|
265
|
+
return store.submit(request.method, async (context) => {
|
|
266
|
+
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");
|
|
267
|
+
return importPacks(names, { force: p.force === true, ...p.revision === void 0 ? {} : { revision: string(p.revision, "\u5BFC\u5165\u8BA1\u5212\u7248\u672C") } });
|
|
268
|
+
});
|
|
269
|
+
}
|
|
213
270
|
case "packs.toggle":
|
|
214
|
-
return store.submit(request.method,
|
|
271
|
+
return store.submit(request.method, async (context) => {
|
|
272
|
+
context.phase("execute", "\u4FDD\u5B58\u4E16\u754C\u5305\u72B6\u6001\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS");
|
|
273
|
+
return togglePack(identifier(p.id), p.enabled === true);
|
|
274
|
+
});
|
|
275
|
+
case "packs.uninstall":
|
|
276
|
+
return store.submit(request.method, async (context) => {
|
|
277
|
+
context.phase("execute", "\u5378\u8F7D\u4E16\u754C\u5305\u5E76\u79FB\u5165\u56DE\u6536\u7AD9\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS");
|
|
278
|
+
return uninstallPack(identifier(p.id));
|
|
279
|
+
});
|
|
280
|
+
case "packs.version": {
|
|
281
|
+
const id = identifier(p.id);
|
|
282
|
+
const version = p.version;
|
|
283
|
+
return store.submit(request.method, async (context) => {
|
|
284
|
+
context.phase("execute", "\u5199\u5165\u8D44\u6E90\u5305\u7248\u672C\uFF0C\u7B49\u5F85\u624B\u52A8\u91CD\u542F BDS");
|
|
285
|
+
return setPackVersion(id, version);
|
|
286
|
+
});
|
|
287
|
+
}
|
|
215
288
|
case "players.list":
|
|
216
289
|
return players();
|
|
217
290
|
case "metrics.read":
|
|
@@ -243,8 +316,8 @@ async function dispatchManagement(request) {
|
|
|
243
316
|
const result = await applyModulePlan(Array.isArray(p.ids) ? p.ids.map(identifier) : []);
|
|
244
317
|
await rebuildModules();
|
|
245
318
|
return result;
|
|
246
|
-
}
|
|
247
|
-
if (p.kind === "bds") return store.submit(request.method, (context) => withStoppedServices(context, [...START_ORDER], () => bdsUpdate(context)
|
|
319
|
+
}));
|
|
320
|
+
if (p.kind === "bds") return store.submit(request.method, (context) => withStoppedServices(context, [...START_ORDER], () => bdsUpdate(context)));
|
|
248
321
|
throw new Error("\u672A\u77E5\u66F4\u65B0\u7C7B\u578B");
|
|
249
322
|
}
|
|
250
323
|
case "deployment.create": {
|
|
@@ -289,10 +362,17 @@ async function dispatchManagement(request) {
|
|
|
289
362
|
const directory = path.join(ROOT, ".sfmc", "backups");
|
|
290
363
|
return { backups: fs.existsSync(directory) ? fs.readdirSync(directory).filter((id) => fs.existsSync(path.join(directory, id, "manifest.json"))) : [] };
|
|
291
364
|
}
|
|
365
|
+
case "backups.create":
|
|
366
|
+
return store.submit(request.method, (context) => createBackup(context));
|
|
292
367
|
case "backups.restore": {
|
|
293
368
|
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");
|
|
294
369
|
return store.submit(request.method, (context) => withStoppedServices(context, [...START_ORDER], () => restoreSnapshot(identifier(p.id), context.phase)));
|
|
295
370
|
}
|
|
371
|
+
case "backups.delete":
|
|
372
|
+
return store.submit(request.method, async (context) => {
|
|
373
|
+
context.phase("execute", "\u5220\u9664\u5907\u4EFD\u76EE\u5F55");
|
|
374
|
+
return deleteSnapshot(identifier(p.id));
|
|
375
|
+
});
|
|
296
376
|
case "startup.plan":
|
|
297
377
|
return startupPlan();
|
|
298
378
|
default:
|
|
@@ -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 { 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, 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, saveDocument, validateDocument } from \"./config.js\";\nimport { listModules, searchModules, identifier, runFetch, readJson, listPacks, togglePack, importPack, playerFiles, savePlayerPermissions, modulePlan, applyModulePlan } from \"./domain.js\";\nimport { attachmentPlan, platformVersion, withStoppedServices, launchPlatformUpdate, restoreSnapshot, 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\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; }\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/**\n * \u6A21\u5757\u6587\u4EF6\u5DF2\u7ECF\u843D\u76D8\u540E\u91CD\u5EFA\u884C\u4E3A\u5305\uFF0C\u5E76\u5728 BDS \u4ECD\u8FD0\u884C\u65F6\u53D1\u9001 reload\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A\u684C\u9762\u7AEF\u5B89\u88C5\u6A21\u5757\u3002\u5B89\u88C5\u53EA\u5199\u5165 modules/packages\uFF0C\u4E0D\u505C\u6B62\u670D\u52A1\uFF1B\n * \u8FD0\u884C\u4E2D\u7684 BDS \u7528 reload \u8F7D\u5165\u65B0\u5305\uFF0C\u672A\u8FD0\u884C\u5219\u7B49\u4E0B\u6B21\u542F\u52A8\u3002\n */\nasync function applyInstalledModule(phase: TaskContext[\"phase\"]) {\n phase(\"execute\", \"\u91CD\u5EFA\u884C\u4E3A\u5305\");\n const rebuilt = await rebuildModules();\n phase(\"reload\", \"\u5411\u8FD0\u884C\u4E2D\u7684 BDS \u53D1\u9001 reload\uFF0C\u4E0D\u505C\u6B62\u670D\u52A1\u5668\");\n await queryServicesRuntimeLocal();\n const bds = services.bds;\n if (!bds.running || !bds.proc?.stdin) return { ...rebuilt, reloaded: false };\n try {\n bds.proc.stdin.write(\"reload\\n\");\n } catch (error) {\n throw new Error(`\u6A21\u5757\u5DF2\u5B89\u88C5\uFF0C\u4F46\u70ED\u91CD\u8F7D\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);\n }\n return { ...rebuilt, reloaded: 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\", \"modules\", \"config\", \"packs\", \"players\", \"updates\", \"operations\", \"metrics\"], 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 names = p.name === \"all\" ? [...START_ORDER] : [service(p.name)];\n return store.submit(request.method, async context => {\n context.phase(\"execute\");\n const rows = await queryServicesRuntimeLocal();\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 (request.method !== \"services.stop\") {\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\": return { entries: readDiskLogs({ limit: Math.min(5000, Math.max(1, Number(p.limit) || 1000)), ...(Array.isArray(p.sources) ? { sources: p.sources.map(value => string(value, \"\u65E5\u5FD7\u6765\u6E90\")) } : {}), ...(Array.isArray(p.levels) ? { levels: p.levels as (\"info\" | \"warn\" | \"error\")[] } : {}) }).map(log => ({ ...log, time: log.time.toISOString() })) };\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 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 return applyInstalledModule(context.phase);\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, context => withStoppedServices(context, [...START_ORDER], async () => {\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 rebuildModules();\n }, true, \"modules\"));\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.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, backupId: context.id } }); }\n });\n }\n case \"packs.list\": return listPacks();\n case \"packs.import\": return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], () => importPack(identifier(p.filename))));\n case \"packs.toggle\": return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], () => togglePack(identifier(p.id), p.enabled === true)));\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; }, true, \"modules\"));\n if (p.kind === \"bds\") return store.submit(request.method, context => withStoppedServices(context, [...START_ORDER], () => bdsUpdate(context), true, \"bds\"));\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.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 \"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 { 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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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|