@sfmc-bds/cli 0.3.2 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/command-surface.d.ts.map +1 -1
  2. package/dist/command-surface.js +5 -6
  3. package/dist/command-surface.js.map +2 -2
  4. package/dist/daemon/client.d.ts +3 -0
  5. package/dist/daemon/client.d.ts.map +1 -1
  6. package/dist/daemon/client.js +38 -8
  7. package/dist/daemon/client.js.map +2 -2
  8. package/dist/daemon/protocol.d.ts +9 -3
  9. package/dist/daemon/protocol.d.ts.map +1 -1
  10. package/dist/daemon/protocol.js.map +2 -2
  11. package/dist/daemon/server.d.ts.map +1 -1
  12. package/dist/daemon/server.js +82 -2
  13. package/dist/daemon/server.js.map +2 -2
  14. package/dist/i18n/locales/en.d.ts +1 -0
  15. package/dist/i18n/locales/en.d.ts.map +1 -1
  16. package/dist/i18n/locales/en.js +1 -0
  17. package/dist/i18n/locales/en.js.map +2 -2
  18. package/dist/i18n/locales/zh-CN.js +1 -0
  19. package/dist/i18n/locales/zh-CN.js.map +2 -2
  20. package/dist/logs.d.ts.map +1 -1
  21. package/dist/logs.js +13 -1
  22. package/dist/logs.js.map +2 -2
  23. package/dist/main.js +14 -184
  24. package/dist/main.js.map +2 -2
  25. package/dist/management/config.d.ts +8 -0
  26. package/dist/management/config.d.ts.map +1 -0
  27. package/dist/management/config.js +107 -0
  28. package/dist/management/config.js.map +7 -0
  29. package/dist/management/deployment.d.ts +7 -0
  30. package/dist/management/deployment.d.ts.map +1 -0
  31. package/dist/management/deployment.js +36 -0
  32. package/dist/management/deployment.js.map +7 -0
  33. package/dist/management/domain.d.ts +65 -0
  34. package/dist/management/domain.d.ts.map +1 -0
  35. package/dist/management/domain.js +137 -0
  36. package/dist/management/domain.js.map +7 -0
  37. package/dist/management/maintenance.d.ts +18 -0
  38. package/dist/management/maintenance.d.ts.map +1 -0
  39. package/dist/management/maintenance.js +214 -0
  40. package/dist/management/maintenance.js.map +7 -0
  41. package/dist/management/platform-worker.d.ts +2 -0
  42. package/dist/management/platform-worker.d.ts.map +1 -0
  43. package/dist/management/platform-worker.js +155 -0
  44. package/dist/management/platform-worker.js.map +7 -0
  45. package/dist/management/server.d.ts +7 -0
  46. package/dist/management/server.d.ts.map +1 -0
  47. package/dist/management/server.js +291 -0
  48. package/dist/management/server.js.map +7 -0
  49. package/dist/management/startup.d.ts +6 -0
  50. package/dist/management/startup.d.ts.map +1 -0
  51. package/dist/management/startup.js +67 -0
  52. package/dist/management/startup.js.map +7 -0
  53. package/dist/management/stdio.d.ts +3 -0
  54. package/dist/management/stdio.d.ts.map +1 -0
  55. package/dist/management/stdio.js +93 -0
  56. package/dist/management/stdio.js.map +7 -0
  57. package/dist/management/tasks.d.ts +21 -0
  58. package/dist/management/tasks.d.ts.map +1 -0
  59. package/dist/management/tasks.js +103 -0
  60. package/dist/management/tasks.js.map +7 -0
  61. package/dist/module-commands.d.ts +2 -2
  62. package/dist/module-commands.d.ts.map +1 -1
  63. package/dist/module-commands.js +28 -24
  64. package/dist/module-commands.js.map +2 -2
  65. package/dist/pack-lifecycle.d.ts.map +1 -1
  66. package/dist/pack-lifecycle.js +2 -0
  67. package/dist/pack-lifecycle.js.map +2 -2
  68. package/dist/runtime-main.d.ts +3 -0
  69. package/dist/runtime-main.d.ts.map +1 -0
  70. package/dist/runtime-main.js +188 -0
  71. package/dist/runtime-main.js.map +7 -0
  72. package/dist/runtime.d.ts +6 -0
  73. package/dist/runtime.d.ts.map +1 -1
  74. package/dist/runtime.js +6 -1
  75. package/dist/runtime.js.map +2 -2
  76. package/dist/services.d.ts +1 -1
  77. package/dist/services.d.ts.map +1 -1
  78. package/dist/services.js +8 -4
  79. package/dist/services.js.map +2 -2
  80. package/dist/world-packs.d.ts.map +1 -1
  81. package/dist/world-packs.js +7 -0
  82. package/dist/world-packs.js.map +2 -2
  83. package/package.json +8 -4
  84. package/scripts/module-install/.sfmc-registry-cache.json +95 -0
  85. package/scripts/module-install/fetch-module.mjs +5 -1
  86. package/scripts/module-install/lib/packages.mjs +3 -6
@@ -0,0 +1,137 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { pathToFileURL } from "node:url";
4
+ import { spawn } from "node:child_process";
5
+ import { resolveRegistryIndex } from "../registry.js";
6
+ import { ROOT, resolveFetchModule } from "../runtime.js";
7
+ import { resolveBdsContext, scanLocalModules } from "../pack-lifecycle.js";
8
+ import { listInstalledWorldPacks, resolvePackRoots, readPackManifestInfo, installPackDirectory, enableInstalledPack, disableInstalledPack, worldPackParentDir } from "@sfmc-bds/bds-tools/world-packs";
9
+ import { atomicJson } from "./tasks.js";
10
+ import { isRetiredPlatformModule } from "@sfmc-bds/sdk/contracts";
11
+ function stripBom(text) {
12
+ return text.charCodeAt(0) === 65279 ? text.slice(1) : text;
13
+ }
14
+ function readJson(file, fallback) {
15
+ try {
16
+ return JSON.parse(stripBom(fs.readFileSync(file, "utf8")));
17
+ } catch (error) {
18
+ if (error.code === "ENOENT") return fallback;
19
+ throw error;
20
+ }
21
+ }
22
+ function identifier(value) {
23
+ if (typeof value !== "string" || !/^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$/.test(value) || value.includes("..")) throw new Error("\u975E\u6CD5\u6807\u8BC6\u7B26");
24
+ return value;
25
+ }
26
+ async function listModules() {
27
+ const rows = (await scanLocalModules()).filter((row) => !isRetiredPlatformModule(row.logicalId));
28
+ const catalog = readJson(path.join(ROOT, "modules", "catalog.json"), {});
29
+ const titles = new Map((catalog.modules ?? []).filter((row) => row.id && row.name).map((row) => [row.id, row.name]));
30
+ return { modules: rows.map((row) => ({ id: row.logicalId, folder: row.folderId, name: titles.get(row.logicalId) || row.logicalId, version: row.version ?? "unknown", enabled: row.enabled, linked: fs.lstatSync(path.join(ROOT, "modules", "packages", row.folderId)).isSymbolicLink() })) };
31
+ }
32
+ function fetchEntry() {
33
+ const entry = resolveFetchModule();
34
+ if (!entry) throw new Error("\u627E\u4E0D\u5230\u6A21\u5757\u5B89\u88C5\u5668");
35
+ return entry;
36
+ }
37
+ async function searchModules(query) {
38
+ const result = await resolveRegistryIndex();
39
+ return { modules: Object.entries(result.index).filter(([id]) => !isRetiredPlatformModule(id) && id.includes(query)).map(([id, metadata]) => ({ id, ...metadata })), stale: result.stale };
40
+ }
41
+ async function runFetch(args) {
42
+ await runProcess(process.execPath, [fetchEntry(), ...args], ROOT);
43
+ return { changed: true };
44
+ }
45
+ function runProcess(command, args, cwd, onLine) {
46
+ return new Promise((resolve, reject) => {
47
+ const child = spawn(command, args, { cwd, env: { ...process.env, SFMC_ROOT: ROOT, FORCE_COLOR: "0" }, windowsHide: true, stdio: ["ignore", "pipe", "pipe"] });
48
+ let diagnostic = "";
49
+ for (const stream of [child.stdout, child.stderr]) stream.on("data", (chunk) => {
50
+ const text = chunk.toString();
51
+ diagnostic = (diagnostic + text).slice(-6e3);
52
+ onLine?.(text);
53
+ });
54
+ child.on("error", reject);
55
+ child.on("close", (code) => code === 0 ? resolve() : reject(new Error(`\u5B50\u8FDB\u7A0B\u5931\u8D25 (${code}): ${diagnostic}`)));
56
+ });
57
+ }
58
+ async function modulePlan(ids = []) {
59
+ const url = pathToFileURL(path.join(path.dirname(fetchEntry()), "lib", "module-update.mjs")).href;
60
+ const api = await import(url);
61
+ return api.planModuleUpdates({ root: ROOT, ids });
62
+ }
63
+ async function applyModulePlan(ids) {
64
+ const directory = path.dirname(fetchEntry());
65
+ const api = await import(pathToFileURL(path.join(directory, "lib", "module-update.mjs")).href);
66
+ const fetchApi = await import(pathToFileURL(fetchEntry()).href);
67
+ const plan = await api.planModuleUpdates({ root: ROOT, ids });
68
+ const result = await api.applyModuleUpgrades(plan.upgrades, { root: ROOT, failMode: plan.failMode, install: fetchApi.installPreservingLock, resync: api.resyncInstalledCatalog });
69
+ if (result.failed.length) throw new Error(JSON.stringify(result.failed));
70
+ return result;
71
+ }
72
+ function listPacks() {
73
+ const context = resolveBdsContext();
74
+ return { packs: listInstalledWorldPacks(context.bdsRoot, context.levelName).map((pack) => ({ id: pack.uuid, name: pack.name, kind: pack.kind, enabled: pack.enabled, version: pack.version.join(".") })) };
75
+ }
76
+ async function togglePack(id, enabled) {
77
+ const context = resolveBdsContext();
78
+ const pack = listInstalledWorldPacks(context.bdsRoot, context.levelName).find((row) => row.uuid === id);
79
+ if (!pack) throw new Error("\u627E\u4E0D\u5230\u4E16\u754C\u5305");
80
+ if (enabled) await enableInstalledPack({ ...context, info: { uuid: pack.uuid, version: pack.version, kind: pack.kind, name: pack.name } });
81
+ else await disableInstalledPack({ ...context, kind: pack.kind, packUuid: pack.uuid, version: pack.version });
82
+ return { changed: true, restartRequired: true };
83
+ }
84
+ async function importPack(filename) {
85
+ const inbox = path.resolve(ROOT, "packs", "_desktop-inbox");
86
+ const file = path.resolve(inbox, identifier(filename));
87
+ if (!file.startsWith(inbox + path.sep) || !fs.existsSync(file)) throw new Error("\u4E16\u754C\u5305\u5C1A\u672A\u4E0A\u4F20\u5230\u5B9E\u4F8B\u6536\u4EF6\u7BB1");
88
+ const context = resolveBdsContext();
89
+ const resolved = await resolvePackRoots(file);
90
+ try {
91
+ if (!resolved.roots.length) throw new Error("\u5F52\u6863\u4E0D\u542B\u53EF\u8BC6\u522B\u7684\u4E16\u754C\u5305");
92
+ for (const root of resolved.roots) {
93
+ const info = readPackManifestInfo(root);
94
+ if (!info) throw new Error("\u4E16\u754C\u5305 manifest \u65E0\u6548");
95
+ const result = await installPackDirectory({ srcDir: root, destParent: worldPackParentDir(context.bdsRoot, context.levelName, info.kind) });
96
+ if (!result.ok) throw new Error(result.reason ?? "\u5B89\u88C5\u5931\u8D25\uFF1B\u53EF\u80FD\u4E0E\u5DF2\u6709\u5305\u51B2\u7A81");
97
+ await enableInstalledPack({ ...context, info });
98
+ }
99
+ } finally {
100
+ resolved.dispose?.();
101
+ }
102
+ return { changed: true, restartRequired: true };
103
+ }
104
+ function playerFiles() {
105
+ const bds = resolveBdsContext().bdsRoot;
106
+ return { allowlist: path.join(bds, "allowlist.json"), permissions: path.join(bds, "permissions.json"), sfmcPermissions: path.join(ROOT, "configs", "permissions.json") };
107
+ }
108
+ function savePlayerPermissions(kind, entries) {
109
+ const files = playerFiles();
110
+ if (!(kind in files) || !Array.isArray(entries)) throw new Error("\u975E\u6CD5\u73A9\u5BB6\u6743\u9650\u7C7B\u578B\u6216\u5185\u5BB9");
111
+ for (const entry of entries) {
112
+ if (!entry || typeof entry !== "object") throw new Error("\u6743\u9650\u6761\u76EE\u5FC5\u987B\u4E3A\u5BF9\u8C61");
113
+ const row = entry;
114
+ if (kind === "allowlist" && (typeof row.name !== "string" || /[\r\n]/.test(row.name))) throw new Error("\u5141\u8BB8\u540D\u5355\u9700\u63D0\u4F9B\u5408\u6CD5\u73A9\u5BB6\u540D\u79F0");
115
+ if (kind === "permissions" && (typeof row.xuid !== "string" || !/^\d+$/.test(row.xuid) || !["visitor", "member", "operator"].includes(String(row.permission)))) throw new Error("BDS \u6743\u9650\u9700\u6709\u6548 XUID \u548C\u6743\u9650\u7B49\u7EA7");
116
+ if (kind === "sfmcPermissions" && (typeof row.player_name !== "string" || !row.player_name.trim() || /[\r\n\0]/.test(row.player_name) || !Number.isInteger(row.level) || Number(row.level) < 0 || Number(row.level) > 3)) throw new Error("SFMC \u6743\u9650\u9700\u5408\u6CD5\u73A9\u5BB6\u540D\u53CA 0 \u5230 3 \u7684\u6574\u6570\u7B49\u7EA7");
117
+ }
118
+ atomicJson(files[kind], entries);
119
+ return { saved: true };
120
+ }
121
+ export {
122
+ applyModulePlan,
123
+ identifier,
124
+ importPack,
125
+ listModules,
126
+ listPacks,
127
+ modulePlan,
128
+ playerFiles,
129
+ readJson,
130
+ runFetch,
131
+ runProcess,
132
+ savePlayerPermissions,
133
+ searchModules,
134
+ stripBom,
135
+ togglePack
136
+ };
137
+ //# sourceMappingURL=domain.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/management/domain.ts"],
4
+ "sourcesContent": ["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { spawn } from \"node:child_process\";\nimport { resolveRegistryIndex } from \"../registry.js\";\nimport { ROOT, resolveFetchModule } from \"../runtime.js\";\nimport { resolveBdsContext, scanLocalModules } from \"../pack-lifecycle.js\";\nimport { listInstalledWorldPacks, resolvePackRoots, readPackManifestInfo, installPackDirectory, enableInstalledPack, disableInstalledPack, worldPackParentDir } from \"@sfmc-bds/bds-tools/world-packs\";\nimport { atomicJson } from \"./tasks.js\";\nimport { isRetiredPlatformModule } from \"@sfmc-bds/sdk/contracts\";\n\n/**\n * \u53BB\u6389 UTF-8 BOM\u3002\n * \u4F7F\u7528\u573A\u666F\uFF1A\u7F16\u8F91\u5668\u6216 BDS \u5199\u51FA\u7684 JSON\uFF08\u4F8B\u5982 configs/permissions.json\uFF09\u5E38\u5E26 BOM\uFF0C\u76F4\u63A5 JSON.parse \u4F1A\u5931\u8D25\u3002\n */\nexport function stripBom(text: string): string {\n return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;\n}\nexport function readJson<T>(file: string, fallback: T): T {\n try { return JSON.parse(stripBom(fs.readFileSync(file, \"utf8\"))) as T; }\n catch (error) { if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return fallback; throw error; }\n}\nexport function identifier(value: unknown): string {\n if (typeof value !== \"string\" || !/^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,127}$/.test(value) || value.includes(\"..\")) throw new Error(\"\u975E\u6CD5\u6807\u8BC6\u7B26\");\n return value;\n}\nexport async function listModules() {\n const rows = (await scanLocalModules()).filter(row => !isRetiredPlatformModule(row.logicalId));\n // \u76EE\u5F55\u91CC\u7684\u5C55\u793A\u540D\u6765\u81EA modules/catalog.json\uFF1B\u6CA1\u6709\u4E2D\u6587\u540D\u65F6\u4ECD\u7528\u903B\u8F91 id\uFF0C\u907F\u514D\u754C\u9762\u53EA\u5269\u6587\u4EF6\u5939\u540D\u3002\n const catalog = readJson<{ modules?: { id?: string; name?: string }[] }>(path.join(ROOT, \"modules\", \"catalog.json\"), {});\n const titles = new Map((catalog.modules ?? []).filter(row => row.id && row.name).map(row => [row.id!, row.name!]));\n return { modules: rows.map(row => ({ id: row.logicalId, folder: row.folderId, name: titles.get(row.logicalId) || row.logicalId, version: row.version ?? \"unknown\", enabled: row.enabled, linked: fs.lstatSync(path.join(ROOT, \"modules\", \"packages\", row.folderId)).isSymbolicLink() })) };\n}\nfunction fetchEntry() { const entry = resolveFetchModule(); if (!entry) throw new Error(\"\u627E\u4E0D\u5230\u6A21\u5757\u5B89\u88C5\u5668\"); return entry; }\nexport async function searchModules(query: string) {\n const result = await resolveRegistryIndex();\n return { modules: Object.entries(result.index).filter(([id]) => !isRetiredPlatformModule(id) && id.includes(query)).map(([id, metadata]) => ({ id, ...metadata })), stale: result.stale };\n}\nexport async function runFetch(args: string[]) {\n await runProcess(process.execPath, [fetchEntry(), ...args], ROOT);\n return { changed: true };\n}\nexport function runProcess(command: string, args: string[], cwd: string, onLine?: (text: string) => void): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, { cwd, env: { ...process.env, SFMC_ROOT: ROOT, FORCE_COLOR: \"0\" }, windowsHide: true, stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n let diagnostic = \"\";\n for (const stream of [child.stdout, child.stderr]) stream.on(\"data\", (chunk: Buffer) => { const text = chunk.toString(); diagnostic = (diagnostic + text).slice(-6000); onLine?.(text); });\n child.on(\"error\", reject); child.on(\"close\", code => code === 0 ? resolve() : reject(new Error(`\u5B50\u8FDB\u7A0B\u5931\u8D25 (${code}): ${diagnostic}`)));\n });\n}\nexport async function modulePlan(ids: string[] = []) {\n const url = pathToFileURL(path.join(path.dirname(fetchEntry()), \"lib\", \"module-update.mjs\")).href;\n const api = await import(url) as { planModuleUpdates: (options: { root: string; ids: string[] }) => Promise<unknown> };\n return api.planModuleUpdates({ root: ROOT, ids });\n}\nexport async function applyModulePlan(ids: string[]) {\n const directory = path.dirname(fetchEntry());\n const api = await import(pathToFileURL(path.join(directory, \"lib\", \"module-update.mjs\")).href) as {\n planModuleUpdates: (options: { root: string; ids: string[] }) => Promise<{ upgrades: { id: string; spec: string }[]; failMode: \"abort\" | \"continue\" }>;\n applyModuleUpgrades: (upgrades: unknown[], deps: object) => Promise<{ failed: { id: string; message: string }[] }>;\n resyncInstalledCatalog: (id: string) => void;\n };\n const fetchApi = await import(pathToFileURL(fetchEntry()).href) as { installPreservingLock: (id: string, spec: string) => Promise<void> };\n const plan = await api.planModuleUpdates({ root: ROOT, ids });\n const result = await api.applyModuleUpgrades(plan.upgrades, { root: ROOT, failMode: plan.failMode, install: fetchApi.installPreservingLock, resync: api.resyncInstalledCatalog });\n if (result.failed.length) throw new Error(JSON.stringify(result.failed));\n return result;\n}\nexport function listPacks() {\n const context = resolveBdsContext();\n return { packs: listInstalledWorldPacks(context.bdsRoot, context.levelName).map(pack => ({ id: pack.uuid, name: pack.name, kind: pack.kind, enabled: pack.enabled, version: pack.version.join(\".\") })) };\n}\nexport async function togglePack(id: string, enabled: boolean) {\n const context = resolveBdsContext();\n const pack = listInstalledWorldPacks(context.bdsRoot, context.levelName).find(row => row.uuid === id);\n if (!pack) throw new Error(\"\u627E\u4E0D\u5230\u4E16\u754C\u5305\");\n if (enabled) await enableInstalledPack({ ...context, info: { uuid: pack.uuid, version: pack.version, kind: pack.kind, name: pack.name } });\n else await disableInstalledPack({ ...context, kind: pack.kind, packUuid: pack.uuid, version: pack.version });\n return { changed: true, restartRequired: true };\n}\nexport async function importPack(filename: string) {\n const inbox = path.resolve(ROOT, \"packs\", \"_desktop-inbox\");\n const file = path.resolve(inbox, identifier(filename));\n if (!file.startsWith(inbox + path.sep) || !fs.existsSync(file)) throw new Error(\"\u4E16\u754C\u5305\u5C1A\u672A\u4E0A\u4F20\u5230\u5B9E\u4F8B\u6536\u4EF6\u7BB1\");\n const context = resolveBdsContext();\n const resolved = await resolvePackRoots(file);\n try {\n if (!resolved.roots.length) throw new Error(\"\u5F52\u6863\u4E0D\u542B\u53EF\u8BC6\u522B\u7684\u4E16\u754C\u5305\");\n for (const root of resolved.roots) {\n const info = readPackManifestInfo(root);\n if (!info) throw new Error(\"\u4E16\u754C\u5305 manifest \u65E0\u6548\");\n const result = await installPackDirectory({ srcDir: root, destParent: worldPackParentDir(context.bdsRoot, context.levelName, info.kind) });\n if (!result.ok) throw new Error(result.reason ?? \"\u5B89\u88C5\u5931\u8D25\uFF1B\u53EF\u80FD\u4E0E\u5DF2\u6709\u5305\u51B2\u7A81\");\n await enableInstalledPack({ ...context, info });\n }\n } finally { resolved.dispose?.(); }\n return { changed: true, restartRequired: true };\n}\nexport function playerFiles() {\n const bds = resolveBdsContext().bdsRoot;\n return { allowlist: path.join(bds, \"allowlist.json\"), permissions: path.join(bds, \"permissions.json\"), sfmcPermissions: path.join(ROOT, \"configs\", \"permissions.json\") };\n}\nexport function savePlayerPermissions(kind: string, entries: unknown) {\n const files = playerFiles();\n if (!(kind in files) || !Array.isArray(entries)) throw new Error(\"\u975E\u6CD5\u73A9\u5BB6\u6743\u9650\u7C7B\u578B\u6216\u5185\u5BB9\");\n for (const entry of entries) {\n if (!entry || typeof entry !== \"object\") throw new Error(\"\u6743\u9650\u6761\u76EE\u5FC5\u987B\u4E3A\u5BF9\u8C61\");\n const row = entry as Record<string, unknown>;\n if (kind === \"allowlist\" && (typeof row.name !== \"string\" || /[\\r\\n]/.test(row.name))) throw new Error(\"\u5141\u8BB8\u540D\u5355\u9700\u63D0\u4F9B\u5408\u6CD5\u73A9\u5BB6\u540D\u79F0\");\n if (kind === \"permissions\" && (typeof row.xuid !== \"string\" || !/^\\d+$/.test(row.xuid) || ![\"visitor\", \"member\", \"operator\"].includes(String(row.permission)))) throw new Error(\"BDS \u6743\u9650\u9700\u6709\u6548 XUID \u548C\u6743\u9650\u7B49\u7EA7\");\n if (kind === \"sfmcPermissions\" && (typeof row.player_name !== \"string\" || !row.player_name.trim() || /[\\r\\n\\0]/.test(row.player_name) || !Number.isInteger(row.level) || Number(row.level) < 0 || Number(row.level) > 3)) throw new Error(\"SFMC \u6743\u9650\u9700\u5408\u6CD5\u73A9\u5BB6\u540D\u53CA 0 \u5230 3 \u7684\u6574\u6570\u7B49\u7EA7\");\n }\n atomicJson(files[kind as keyof typeof files], entries);\n return { saved: true };\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,18 @@
1
+ import { type ServiceName } from "../services.js";
2
+ import { type TaskContext, type TaskStore } from "./tasks.js";
3
+ import type { AttachmentPlan } from "@sfmc-bds/management";
4
+ export declare function platformVersion(): string;
5
+ export declare function attachmentPlan(): Promise<AttachmentPlan>;
6
+ export declare function stopForMaintenance(names: ServiceName[], phase: TaskContext["phase"]): Promise<ServiceName[]>;
7
+ export declare function restoreRunning(names: ServiceName[], phase: TaskContext["phase"]): Promise<void>;
8
+ export declare function verifyRunning(names: ServiceName[]): Promise<void>;
9
+ export declare function createSnapshot(id: string, phase: TaskContext["phase"]): Promise<string>;
10
+ export declare function restoreSnapshot(id: string, phase: TaskContext["phase"]): Promise<{
11
+ restored: string;
12
+ }>;
13
+ export declare function withStoppedServices<T>(context: TaskContext, names: ServiceName[], action: () => Promise<T>, backup?: boolean, rollbackPrograms?: "modules" | "bds"): Promise<T>;
14
+ export declare function launchPlatformUpdate(store: TaskStore, context: TaskContext, target: string): Promise<{
15
+ detached: boolean;
16
+ }>;
17
+ export declare function runPnpm(args: string[], cwd: string): Promise<void>;
18
+ //# sourceMappingURL=maintenance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maintenance.d.ts","sourceRoot":"","sources":["../../src/management/maintenance.ts"],"names":[],"mappings":"AAMA,OAAO,EAAoD,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAEpG,OAAO,EAAc,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAE1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAY3D,wBAAgB,eAAe,IAAI,MAAM,CASxC;AACD,wBAAsB,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC,CAkB9D;AACD,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAUlH;AACD,wBAAsB,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,iBAOrF;AACD,wBAAsB,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,iBAWvD;AAMD,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,mBAc3E;AACD,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC;;GAiB5E;AAuBD,wBAAsB,mBAAmB,CAAC,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,UAAO,EAAE,gBAAgB,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAqBlL;AACD,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM;;GAmBhG;AACD,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,iBASxD"}
@@ -0,0 +1,214 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { createRequire } from "node:module";
4
+ import { spawn } from "node:child_process";
5
+ import { fileURLToPath } from "node:url";
6
+ import { ROOT, isMonorepoLayout, isSourceCheckout } from "../runtime.js";
7
+ import { queryServicesRuntimeLocal, services, START_ORDER } from "../services.js";
8
+ import { resolveBdsContext } from "../pack-lifecycle.js";
9
+ import { atomicJson } from "./tasks.js";
10
+ import { readJson, runProcess } from "./domain.js";
11
+ import { isDaemonServer } from "../daemon/role.js";
12
+ import { callDaemon } from "../daemon/client.js";
13
+ async function runtimeRows() {
14
+ if (isDaemonServer()) return queryServicesRuntimeLocal();
15
+ const result = await callDaemon("status");
16
+ if (result.kind !== "status") throw new Error("\u65E0\u6CD5\u8BFB\u53D6\u5B88\u62A4\u8FDB\u7A0B\u670D\u52A1\u72B6\u6001");
17
+ return result.rows;
18
+ }
19
+ const require2 = createRequire(import.meta.url);
20
+ function platformVersion() {
21
+ if (isMonorepoLayout(ROOT)) return readJson(path.join(ROOT, "packages", "meta", "package.json"), { version: "unknown" }).version;
22
+ if (process.env.SFMC_PLATFORM_VERSION) return process.env.SFMC_PLATFORM_VERSION;
23
+ const active = readJson(path.join(ROOT, ".sfmc", "runtime", "active.json"), {});
24
+ if (active.version) return active.version;
25
+ const deployed = readJson(path.join(ROOT, "node_modules", "@sfmc-bds", "sfmc", "package.json"), {});
26
+ if (deployed.version) return deployed.version;
27
+ try {
28
+ return require2("@sfmc-bds/sfmc/package.json").version;
29
+ } catch {
30
+ return readJson(path.join(fileURLToPath(new URL("../../..", import.meta.url)), "package.json"), { version: "unknown" }).version;
31
+ }
32
+ }
33
+ async function attachmentPlan() {
34
+ const development = isMonorepoLayout(ROOT) || isSourceCheckout();
35
+ const currentVersion = platformVersion();
36
+ let targetVersion = currentVersion;
37
+ if (!development) {
38
+ const response = await fetch("https://registry.npmjs.org/@sfmc-bds%2fsfmc/latest", { signal: AbortSignal.timeout(15e3) });
39
+ if (!response.ok) throw new Error(`\u5E73\u53F0\u7248\u672C\u68C0\u67E5\u5931\u8D25 (${response.status})`);
40
+ const metadata = await response.json();
41
+ if (!metadata.version || !/^\d+\.\d+\.\d+$/.test(metadata.version)) throw new Error("latest \u6CA1\u6709\u6307\u5411\u6709\u6548\u7684\u7A33\u5B9A\u5E73\u53F0\u7248\u672C");
42
+ const currentBase = /^(\d+)\.(\d+)\.(\d+)(?:-[\w.-]+)?$/.exec(currentVersion);
43
+ const latest = metadata.version.split(".").map(Number);
44
+ const current = currentBase?.slice(1).map(Number);
45
+ const difference = current && latest.map((value, index) => value - current[index]).find((value) => value !== 0);
46
+ if (!current || difference === void 0 || difference >= 0) targetVersion = metadata.version;
47
+ }
48
+ const rows = await runtimeRows();
49
+ return { currentVersion, targetVersion, development, upgradeRequired: !development && targetVersion !== currentVersion, externalServices: rows.filter((row) => row.running && row.ownership === "external").map((row) => row.name), steps: development ? ["\u4FDD\u7559\u6E90\u7801\u5DE5\u4F5C\u533A\uFF0C\u8FDE\u63A5\u5F53\u524D\u5F00\u53D1\u90E8\u7F72"] : ["\u4E0B\u8F7D\u56FA\u5B9A\u7248\u672C\u7684\u5E73\u53F0\u4F9D\u8D56\u7EC4\u5408", "\u505C\u6B62\u53D7\u5F71\u54CD\u670D\u52A1\u5E76\u786E\u8BA4\u8FDB\u7A0B\u9000\u51FA", "\u5907\u4EFD\u914D\u7F6E\u3001\u6A21\u5757\u3001\u6570\u636E\u5E93\u4E0E\u4E16\u754C", "\u5207\u6362\u5E73\u53F0\u5E76\u9A8C\u8BC1", "\u6062\u590D\u6B64\u524D\u8FD0\u884C\u7684\u670D\u52A1"] };
50
+ }
51
+ async function stopForMaintenance(names, phase) {
52
+ const before = await queryServicesRuntimeLocal();
53
+ const affected = before.filter((row) => names.includes(row.name) && row.running);
54
+ if (affected.some((row) => row.ownership === "external")) throw Object.assign(new Error("\u5B58\u5728\u65E0\u6CD5\u901A\u8FC7\u5F53\u524D\u5B88\u62A4\u8FDB\u7A0B\u4F18\u96C5\u505C\u6B62\u7684\u5916\u90E8\u670D\u52A1\uFF1B\u8BF7\u5148\u901A\u8FC7\u539F\u7BA1\u7406\u5668\u505C\u6B62\u540E\u91CD\u65B0\u63A5\u5165"), { code: "conflict" });
55
+ phase("stop-services", "\u4F18\u96C5\u505C\u6B62\u5E76\u786E\u8BA4\u8FDB\u7A0B\u9000\u51FA");
56
+ const running = affected.map((row) => row.name);
57
+ for (const name of [...START_ORDER].reverse().filter((name2) => names.includes(name2))) await services[name].stop(false, false);
58
+ const after = await queryServicesRuntimeLocal();
59
+ if (after.some((row) => names.includes(row.name) && row.running)) throw new Error("\u670D\u52A1\u672A\u5B8C\u5168\u9000\u51FA\uFF0C\u5DF2\u4E2D\u6B62\u6587\u4EF6\u64CD\u4F5C");
60
+ return running;
61
+ }
62
+ async function restoreRunning(names, phase) {
63
+ phase("restore", "\u6062\u590D\u7EF4\u62A4\u524D\u8FD0\u884C\u7684\u670D\u52A1");
64
+ for (const name of START_ORDER.filter((name2) => names.includes(name2))) {
65
+ const result = await services[name].start();
66
+ if (result.status === "skipped") throw new Error(`\u6062\u590D ${name} \u5931\u8D25: ${result.reason}`);
67
+ }
68
+ await verifyRunning(names);
69
+ }
70
+ async function verifyRunning(names) {
71
+ if (!names.length) return;
72
+ await new Promise((resolve) => setTimeout(resolve, 2e3));
73
+ for (const name of names) {
74
+ if (!services[name].running || !services[name].pid) throw new Error(`${name} \u542F\u52A8\u540E\u5DF2\u9000\u51FA`);
75
+ }
76
+ if (names.includes("db")) {
77
+ const cfg = readJson(path.join(ROOT, "configs", "db_config.json"), {});
78
+ const response = await fetch(`http://127.0.0.1:${cfg.db_port ?? 3001}/api/sfmc/status`, { headers: cfg.http_auth ? { authorization: `Bearer ${cfg.http_auth}` } : {}, signal: AbortSignal.timeout(5e3) });
79
+ if (!response.ok) throw new Error(`DB \u5065\u5EB7\u68C0\u67E5\u5931\u8D25 (${response.status})`);
80
+ }
81
+ }
82
+ function snapshotTargets() {
83
+ const db = readJson(path.join(ROOT, "configs", "db_config.json"), {});
84
+ const bds = resolveBdsContext().bdsRoot;
85
+ return { configs: path.join(ROOT, "configs"), modules: path.join(ROOT, "modules"), data: path.dirname(path.resolve(ROOT, db.dbDir ?? "data/sfmc_data.db")), bds };
86
+ }
87
+ async function createSnapshot(id, phase) {
88
+ phase("backup", "\u521B\u5EFA\u5DF2\u505C\u670D\u7684\u4E00\u81F4\u5907\u4EFD");
89
+ const destination = path.join(ROOT, ".sfmc", "backups", id);
90
+ fs.mkdirSync(destination, { recursive: true });
91
+ const targets = snapshotTargets();
92
+ for (const target of Object.values(targets)) {
93
+ const absolute = path.resolve(target);
94
+ if (absolute === path.parse(absolute).root || absolute === path.resolve(ROOT) || destination.startsWith(absolute + path.sep)) throw new Error("\u5907\u4EFD\u76EE\u6807\u5305\u542B\u5B9E\u4F8B\u6839\u76EE\u5F55\u6216\u5907\u4EFD\u76EE\u5F55\uFF0C\u5DF2\u4E2D\u6B62");
95
+ }
96
+ for (const [key, target] of Object.entries(targets)) {
97
+ if (fs.existsSync(target)) await fs.promises.cp(target, path.join(destination, key), { recursive: true, dereference: false });
98
+ }
99
+ atomicJson(path.join(destination, "manifest.json"), { createdAt: (/* @__PURE__ */ new Date()).toISOString(), targets, complete: true });
100
+ return destination;
101
+ }
102
+ async function restoreSnapshot(id, phase) {
103
+ if (!/^[a-zA-Z0-9-]{1,80}$/.test(id)) throw new Error("\u975E\u6CD5\u5907\u4EFD\u7F16\u53F7");
104
+ const source = path.join(ROOT, ".sfmc", "backups", id);
105
+ const manifest = readJson(path.join(source, "manifest.json"), { complete: false, targets: {} });
106
+ if (!manifest.complete) throw new Error("\u5907\u4EFD\u4E0D\u5B8C\u6574\uFF0C\u7981\u6B62\u6062\u590D");
107
+ const targets = snapshotTargets();
108
+ phase("restore-data", "\u6309\u7528\u6237\u660E\u786E\u9009\u62E9\u6062\u590D\u914D\u7F6E\u3001\u6A21\u5757\u3001\u6570\u636E\u5E93\u548C\u4E16\u754C");
109
+ for (const [key, target] of Object.entries(targets)) {
110
+ if (path.resolve(manifest.targets[key] ?? "") !== path.resolve(target)) throw new Error("\u5907\u4EFD\u76EE\u6807\u4E0E\u5F53\u524D\u90E8\u7F72\u4E0D\u4E00\u81F4");
111
+ const saved = path.join(source, key);
112
+ if (!fs.existsSync(saved)) continue;
113
+ const absolute = path.resolve(target);
114
+ if (absolute === path.parse(absolute).root || absolute === path.resolve(ROOT) || fs.lstatSync(saved).isSymbolicLink()) throw new Error("\u4E0D\u5B89\u5168\u7684\u6062\u590D\u76EE\u6807");
115
+ await fs.promises.rm(absolute, { recursive: true, force: true });
116
+ await fs.promises.cp(saved, absolute, { recursive: true, dereference: false });
117
+ }
118
+ return { restored: id };
119
+ }
120
+ async function restoreProgramSnapshot(id, kind) {
121
+ const source = path.join(ROOT, ".sfmc", "backups", id);
122
+ const manifest = readJson(path.join(source, "manifest.json"), { complete: false, targets: {} });
123
+ const targets = snapshotTargets();
124
+ if (!manifest.complete || path.resolve(manifest.targets[kind] ?? "") !== path.resolve(targets[kind])) throw new Error("\u7A0B\u5E8F\u5907\u4EFD\u4E0D\u5B8C\u6574\u6216\u76EE\u6807\u4E0D\u5339\u914D");
125
+ const saved = path.join(source, kind);
126
+ if (kind === "modules") {
127
+ if (!fs.existsSync(saved)) return;
128
+ await fs.promises.rm(targets.modules, { recursive: true, force: true });
129
+ await fs.promises.cp(saved, targets.modules, { recursive: true, dereference: false });
130
+ return;
131
+ }
132
+ const cfg = readJson(path.join(ROOT, "configs", "bds_updater.json"), {});
133
+ const preserved = /* @__PURE__ */ new Set(["worlds", "config", "server.properties", "allowlist.json", "whitelist.json", "permissions.json", ...(cfg.preserve ?? []).map((name) => name.split(/[\\/]/)[0])]);
134
+ if (!fs.existsSync(saved)) throw new Error("\u7F3A\u5C11\u539F BDS \u7A0B\u5E8F\u5907\u4EFD");
135
+ const target = path.resolve(targets.bds);
136
+ if (target === path.parse(target).root || target === path.resolve(ROOT)) throw new Error("\u4E0D\u5B89\u5168\u7684\u7A0B\u5E8F\u56DE\u9000\u76EE\u6807");
137
+ fs.mkdirSync(target, { recursive: true });
138
+ for (const entry of fs.readdirSync(target)) if (!preserved.has(entry)) await fs.promises.rm(path.join(target, entry), { recursive: true, force: true });
139
+ for (const entry of fs.readdirSync(saved)) if (!preserved.has(entry)) await fs.promises.cp(path.join(saved, entry), path.join(target, entry), { recursive: true, dereference: false });
140
+ }
141
+ async function withStoppedServices(context, names, action, backup = true, rollbackPrograms) {
142
+ const running = await stopForMaintenance(names, context.phase);
143
+ try {
144
+ if (backup) await createSnapshot(context.id, context.phase);
145
+ context.phase("execute");
146
+ const result = await action();
147
+ context.phase("verify");
148
+ await restoreRunning(running, context.phase);
149
+ return result;
150
+ } catch (error) {
151
+ for (const name of [...START_ORDER].reverse().filter((name2) => running.includes(name2))) await services[name].stop(false, false).catch(() => {
152
+ });
153
+ let programRolledBack = false;
154
+ let rollbackError;
155
+ if (rollbackPrograms) {
156
+ context.phase("rollback-program", "\u56DE\u9000\u7A0B\u5E8F\u7248\u672C\uFF0C\u4FDD\u7559\u5F53\u524D\u73A9\u5BB6\u6570\u636E");
157
+ try {
158
+ await restoreProgramSnapshot(context.id, rollbackPrograms);
159
+ programRolledBack = true;
160
+ } catch (failure) {
161
+ rollbackError = String(failure);
162
+ }
163
+ }
164
+ throw Object.assign(new Error(`\u7EF4\u62A4\u5931\u8D25\uFF0C\u670D\u52A1\u4FDD\u6301\u505C\u6B62\uFF1B\u5907\u4EFD\u7F16\u53F7 ${context.id}: ${error instanceof Error ? error.message : String(error)}`), { code: "io", details: { backupId: context.id, programRolledBack, dataRestoreRequired: Boolean(rollbackPrograms), ...rollbackError ? { rollbackError } : {}, ...error.details ?? {} } });
165
+ }
166
+ }
167
+ async function launchPlatformUpdate(store, context, target) {
168
+ if (isMonorepoLayout(ROOT)) throw new Error("\u6E90\u7801\u90E8\u7F72\u4E0D\u8986\u76D6\u5DE5\u4F5C\u533A\uFF1B\u8BF7\u4F7F\u7528\u6B63\u5E38\u5F00\u53D1\u53D1\u5E03\u6D41\u7A0B");
169
+ if (!/^\d+\.\d+\.\d+$/.test(target)) throw new Error("\u9700\u8981\u56FA\u5B9A\u7A33\u5B9A\u7248\u672C");
170
+ const rows = await runtimeRows();
171
+ if (rows.some((row) => row.running && row.ownership === "external")) throw new Error("\u5916\u90E8\u670D\u52A1\u5FC5\u987B\u5148\u901A\u8FC7\u539F\u7BA1\u7406\u5668\u4F18\u96C5\u505C\u6B62");
172
+ const request = path.join(ROOT, ".sfmc", "operations", `${context.id}.request.json`);
173
+ const previous = readJson(path.join(ROOT, ".sfmc", "runtime", "active.json"), { entry: fs.existsSync(path.join(ROOT, "node_modules", "@sfmc-bds", "sfmc", "bin", "sfmc.mjs")) ? path.join(ROOT, "node_modules", "@sfmc-bds", "sfmc", "bin", "sfmc.mjs") : process.env.SFMC_DAEMON_ENTRY, version: platformVersion() });
174
+ atomicJson(request, { root: ROOT, id: context.id, target, running: rows.filter((row) => row.running).map((row) => row.name), previous });
175
+ const entry = fileURLToPath(new URL("./platform-worker.js", import.meta.url));
176
+ fs.mkdirSync(path.join(ROOT, ".sfmc", "logs"), { recursive: true });
177
+ const fd = fs.openSync(path.join(ROOT, ".sfmc", "logs", "maintenance.log"), "a");
178
+ const child = spawn(process.execPath, [entry, request], { cwd: ROOT, env: { ...process.env, SFMC_ROOT: ROOT }, detached: true, windowsHide: true, stdio: ["ignore", fd, fd] });
179
+ fs.closeSync(fd);
180
+ await new Promise((resolve, reject) => {
181
+ child.once("spawn", resolve);
182
+ child.once("error", reject);
183
+ });
184
+ child.unref();
185
+ const record = store.get(context.id);
186
+ record.status = "running";
187
+ if (child.pid) record.workerPid = child.pid;
188
+ store.save(record);
189
+ return { detached: true };
190
+ }
191
+ async function runPnpm(args, cwd) {
192
+ const script = process.env.SFMC_PNPM_ENTRY;
193
+ if (script) return runProcess(process.execPath, [script, ...args], cwd);
194
+ const command = process.platform === "win32" ? "pnpm.cmd" : "pnpm";
195
+ const crossSpawn = require2("cross-spawn");
196
+ await new Promise((resolve, reject) => {
197
+ const child = crossSpawn(command, args, { cwd, env: process.env, windowsHide: true, stdio: "ignore" });
198
+ child.on("error", reject);
199
+ child.on("close", (code) => code === 0 ? resolve() : reject(new Error(`pnpm \u6267\u884C\u5931\u8D25 (${code})`)));
200
+ });
201
+ }
202
+ export {
203
+ attachmentPlan,
204
+ createSnapshot,
205
+ launchPlatformUpdate,
206
+ platformVersion,
207
+ restoreRunning,
208
+ restoreSnapshot,
209
+ runPnpm,
210
+ stopForMaintenance,
211
+ verifyRunning,
212
+ withStoppedServices
213
+ };
214
+ //# sourceMappingURL=maintenance.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/management/maintenance.ts"],
4
+ "sourcesContent": ["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport { spawn } from \"node:child_process\";\nimport { fileURLToPath } from \"node:url\";\nimport { ROOT, isMonorepoLayout, isSourceCheckout } from \"../runtime.js\";\nimport { queryServicesRuntimeLocal, services, START_ORDER, type ServiceName } from \"../services.js\";\nimport { resolveBdsContext } from \"../pack-lifecycle.js\";\nimport { atomicJson, type TaskContext, type TaskStore } from \"./tasks.js\";\nimport { readJson, runProcess } from \"./domain.js\";\nimport type { AttachmentPlan } from \"@sfmc-bds/management\";\nimport { isDaemonServer } from \"../daemon/role.js\";\nimport { callDaemon } from \"../daemon/client.js\";\n\nasync function runtimeRows() {\n if (isDaemonServer()) return queryServicesRuntimeLocal();\n const result = await callDaemon(\"status\");\n if (result.kind !== \"status\") throw new Error(\"\u65E0\u6CD5\u8BFB\u53D6\u5B88\u62A4\u8FDB\u7A0B\u670D\u52A1\u72B6\u6001\");\n return result.rows;\n}\n\nconst require = createRequire(import.meta.url);\nexport function platformVersion(): string {\n if (isMonorepoLayout(ROOT)) return readJson<{ version: string }>(path.join(ROOT, \"packages\", \"meta\", \"package.json\"), { version: \"unknown\" }).version;\n if (process.env.SFMC_PLATFORM_VERSION) return process.env.SFMC_PLATFORM_VERSION;\n const active = readJson<{ version?: string }>(path.join(ROOT, \".sfmc\", \"runtime\", \"active.json\"), {});\n if (active.version) return active.version;\n const deployed = readJson<{ version?: string }>(path.join(ROOT, \"node_modules\", \"@sfmc-bds\", \"sfmc\", \"package.json\"), {});\n if (deployed.version) return deployed.version;\n try { return (require(\"@sfmc-bds/sfmc/package.json\") as { version: string }).version; }\n catch { return (readJson<{ version: string }>(path.join(fileURLToPath(new URL(\"../../..\", import.meta.url)), \"package.json\"), { version: \"unknown\" })).version; }\n}\nexport async function attachmentPlan(): Promise<AttachmentPlan> {\n const development = isMonorepoLayout(ROOT) || isSourceCheckout();\n const currentVersion = platformVersion();\n let targetVersion = currentVersion;\n if (!development) {\n const response = await fetch(\"https://registry.npmjs.org/@sfmc-bds%2fsfmc/latest\", { signal: AbortSignal.timeout(15_000) });\n if (!response.ok) throw new Error(`\u5E73\u53F0\u7248\u672C\u68C0\u67E5\u5931\u8D25 (${response.status})`);\n const metadata = await response.json() as { version?: string };\n if (!metadata.version || !/^\\d+\\.\\d+\\.\\d+$/.test(metadata.version)) throw new Error(\"latest \u6CA1\u6709\u6307\u5411\u6709\u6548\u7684\u7A33\u5B9A\u5E73\u53F0\u7248\u672C\");\n // \u72EC\u7ACB\u9884\u89C8\u5305\u53EF\u80FD\u6BD4 npm latest \u66F4\u65B0\uFF1B\u63A5\u5165\u4E0D\u80FD\u628A\u5B83\u964D\u7EA7\u5230\u65E7\u7A33\u5B9A\u7248\u3002\n const currentBase = /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-[\\w.-]+)?$/.exec(currentVersion);\n const latest = metadata.version.split(\".\").map(Number);\n const current = currentBase?.slice(1).map(Number);\n const difference = current && latest.map((value, index) => value - current[index]!).find(value => value !== 0);\n if (!current || difference === undefined || difference >= 0) targetVersion = metadata.version;\n }\n const rows = await runtimeRows();\n return { currentVersion, targetVersion, development, upgradeRequired: !development && targetVersion !== currentVersion, externalServices: rows.filter(row => row.running && row.ownership === \"external\").map(row => row.name), steps: development ? [\"\u4FDD\u7559\u6E90\u7801\u5DE5\u4F5C\u533A\uFF0C\u8FDE\u63A5\u5F53\u524D\u5F00\u53D1\u90E8\u7F72\"] : [\"\u4E0B\u8F7D\u56FA\u5B9A\u7248\u672C\u7684\u5E73\u53F0\u4F9D\u8D56\u7EC4\u5408\", \"\u505C\u6B62\u53D7\u5F71\u54CD\u670D\u52A1\u5E76\u786E\u8BA4\u8FDB\u7A0B\u9000\u51FA\", \"\u5907\u4EFD\u914D\u7F6E\u3001\u6A21\u5757\u3001\u6570\u636E\u5E93\u4E0E\u4E16\u754C\", \"\u5207\u6362\u5E73\u53F0\u5E76\u9A8C\u8BC1\", \"\u6062\u590D\u6B64\u524D\u8FD0\u884C\u7684\u670D\u52A1\"] };\n}\nexport async function stopForMaintenance(names: ServiceName[], phase: TaskContext[\"phase\"]): Promise<ServiceName[]> {\n const before = await queryServicesRuntimeLocal();\n const affected = before.filter(row => names.includes(row.name) && row.running);\n if (affected.some(row => row.ownership === \"external\")) throw Object.assign(new Error(\"\u5B58\u5728\u65E0\u6CD5\u901A\u8FC7\u5F53\u524D\u5B88\u62A4\u8FDB\u7A0B\u4F18\u96C5\u505C\u6B62\u7684\u5916\u90E8\u670D\u52A1\uFF1B\u8BF7\u5148\u901A\u8FC7\u539F\u7BA1\u7406\u5668\u505C\u6B62\u540E\u91CD\u65B0\u63A5\u5165\"), { code: \"conflict\" });\n phase(\"stop-services\", \"\u4F18\u96C5\u505C\u6B62\u5E76\u786E\u8BA4\u8FDB\u7A0B\u9000\u51FA\");\n const running = affected.map(row => row.name);\n for (const name of [...START_ORDER].reverse().filter(name => names.includes(name))) await services[name].stop(false, false);\n const after = await queryServicesRuntimeLocal();\n if (after.some(row => names.includes(row.name) && row.running)) throw new Error(\"\u670D\u52A1\u672A\u5B8C\u5168\u9000\u51FA\uFF0C\u5DF2\u4E2D\u6B62\u6587\u4EF6\u64CD\u4F5C\");\n return running;\n}\nexport async function restoreRunning(names: ServiceName[], phase: TaskContext[\"phase\"]) {\n phase(\"restore\", \"\u6062\u590D\u7EF4\u62A4\u524D\u8FD0\u884C\u7684\u670D\u52A1\");\n for (const name of START_ORDER.filter(name => names.includes(name))) {\n const result = await services[name].start();\n if (result.status === \"skipped\") throw new Error(`\u6062\u590D ${name} \u5931\u8D25: ${result.reason}`);\n }\n await verifyRunning(names);\n}\nexport async function verifyRunning(names: ServiceName[]) {\n if (!names.length) return;\n await new Promise(resolve => setTimeout(resolve, 2000));\n for (const name of names) {\n if (!services[name].running || !services[name].pid) throw new Error(`${name} \u542F\u52A8\u540E\u5DF2\u9000\u51FA`);\n }\n if (names.includes(\"db\")) {\n const cfg = readJson<{ db_port?: number; http_auth?: string }>(path.join(ROOT, \"configs\", \"db_config.json\"), {});\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) throw new Error(`DB \u5065\u5EB7\u68C0\u67E5\u5931\u8D25 (${response.status})`);\n }\n}\nfunction snapshotTargets() {\n const db = readJson<{ dbDir?: string }>(path.join(ROOT, \"configs\", \"db_config.json\"), {});\n const bds = resolveBdsContext().bdsRoot;\n return { configs: path.join(ROOT, \"configs\"), modules: path.join(ROOT, \"modules\"), data: path.dirname(path.resolve(ROOT, db.dbDir ?? \"data/sfmc_data.db\")), bds };\n}\nexport async function createSnapshot(id: string, phase: TaskContext[\"phase\"]) {\n phase(\"backup\", \"\u521B\u5EFA\u5DF2\u505C\u670D\u7684\u4E00\u81F4\u5907\u4EFD\");\n const destination = path.join(ROOT, \".sfmc\", \"backups\", id);\n fs.mkdirSync(destination, { recursive: true });\n const targets = snapshotTargets();\n for (const target of Object.values(targets)) {\n const absolute = path.resolve(target);\n if (absolute === path.parse(absolute).root || absolute === path.resolve(ROOT) || destination.startsWith(absolute + path.sep)) throw new Error(\"\u5907\u4EFD\u76EE\u6807\u5305\u542B\u5B9E\u4F8B\u6839\u76EE\u5F55\u6216\u5907\u4EFD\u76EE\u5F55\uFF0C\u5DF2\u4E2D\u6B62\");\n }\n for (const [key, target] of Object.entries(targets)) {\n if (fs.existsSync(target)) await fs.promises.cp(target, path.join(destination, key), { recursive: true, dereference: false });\n }\n atomicJson(path.join(destination, \"manifest.json\"), { createdAt: new Date().toISOString(), targets, complete: true });\n return destination;\n}\nexport async function restoreSnapshot(id: string, phase: TaskContext[\"phase\"]) {\n if (!/^[a-zA-Z0-9-]{1,80}$/.test(id)) throw new Error(\"\u975E\u6CD5\u5907\u4EFD\u7F16\u53F7\");\n const source = path.join(ROOT, \".sfmc\", \"backups\", id);\n const manifest = readJson<{ complete: boolean; targets: Record<string, string> }>(path.join(source, \"manifest.json\"), { complete: false, targets: {} });\n if (!manifest.complete) throw new Error(\"\u5907\u4EFD\u4E0D\u5B8C\u6574\uFF0C\u7981\u6B62\u6062\u590D\");\n const targets = snapshotTargets();\n phase(\"restore-data\", \"\u6309\u7528\u6237\u660E\u786E\u9009\u62E9\u6062\u590D\u914D\u7F6E\u3001\u6A21\u5757\u3001\u6570\u636E\u5E93\u548C\u4E16\u754C\");\n for (const [key, target] of Object.entries(targets)) {\n if (path.resolve(manifest.targets[key] ?? \"\") !== path.resolve(target)) throw new Error(\"\u5907\u4EFD\u76EE\u6807\u4E0E\u5F53\u524D\u90E8\u7F72\u4E0D\u4E00\u81F4\");\n const saved = path.join(source, key);\n if (!fs.existsSync(saved)) continue;\n const absolute = path.resolve(target);\n if (absolute === path.parse(absolute).root || absolute === path.resolve(ROOT) || fs.lstatSync(saved).isSymbolicLink()) throw new Error(\"\u4E0D\u5B89\u5168\u7684\u6062\u590D\u76EE\u6807\");\n await fs.promises.rm(absolute, { recursive: true, force: true });\n await fs.promises.cp(saved, absolute, { recursive: true, dereference: false });\n }\n return { restored: id };\n}\n/** \u53EA\u56DE\u9000\u7A0B\u5E8F\u5185\u5BB9\uFF0C\u4E16\u754C\u3001\u73A9\u5BB6\u6743\u9650\u548C\u6570\u636E\u5E93\u59CB\u7EC8\u4FDD\u7559\u5728\u5F53\u524D\u72B6\u6001\u3002 */\nasync function restoreProgramSnapshot(id: string, kind: \"modules\" | \"bds\") {\n const source = path.join(ROOT, \".sfmc\", \"backups\", id);\n const manifest = readJson<{ complete: boolean; targets: Record<string, string> }>(path.join(source, \"manifest.json\"), { complete: false, targets: {} });\n const targets = snapshotTargets();\n if (!manifest.complete || path.resolve(manifest.targets[kind] ?? \"\") !== path.resolve(targets[kind])) throw new Error(\"\u7A0B\u5E8F\u5907\u4EFD\u4E0D\u5B8C\u6574\u6216\u76EE\u6807\u4E0D\u5339\u914D\");\n const saved = path.join(source, kind);\n if (kind === \"modules\") {\n if (!fs.existsSync(saved)) return;\n await fs.promises.rm(targets.modules, { recursive: true, force: true });\n await fs.promises.cp(saved, targets.modules, { recursive: true, dereference: false });\n return;\n }\n const cfg = readJson<{ preserve?: string[] }>(path.join(ROOT, \"configs\", \"bds_updater.json\"), {});\n const preserved = new Set([\"worlds\", \"config\", \"server.properties\", \"allowlist.json\", \"whitelist.json\", \"permissions.json\", ...(cfg.preserve ?? []).map(name => name.split(/[\\\\/]/)[0]!)]);\n if (!fs.existsSync(saved)) throw new Error(\"\u7F3A\u5C11\u539F BDS \u7A0B\u5E8F\u5907\u4EFD\");\n const target = path.resolve(targets.bds);\n if (target === path.parse(target).root || target === path.resolve(ROOT)) throw new Error(\"\u4E0D\u5B89\u5168\u7684\u7A0B\u5E8F\u56DE\u9000\u76EE\u6807\");\n fs.mkdirSync(target, { recursive: true });\n for (const entry of fs.readdirSync(target)) if (!preserved.has(entry)) await fs.promises.rm(path.join(target, entry), { recursive: true, force: true });\n for (const entry of fs.readdirSync(saved)) if (!preserved.has(entry)) await fs.promises.cp(path.join(saved, entry), path.join(target, entry), { recursive: true, dereference: false });\n}\nexport async function withStoppedServices<T>(context: TaskContext, names: ServiceName[], action: () => Promise<T>, backup = true, rollbackPrograms?: \"modules\" | \"bds\"): Promise<T> {\n const running = await stopForMaintenance(names, context.phase);\n try {\n if (backup) await createSnapshot(context.id, context.phase);\n context.phase(\"execute\");\n const result = await action();\n context.phase(\"verify\");\n await restoreRunning(running, context.phase);\n return result;\n } catch (error) {\n // \u5931\u8D25\u540E\u4FDD\u6301\u505C\u670D\uFF0C\u4E0D\u731C\u6D4B\u672A\u77E5\u6570\u636E\u8FC1\u79FB\u662F\u5426\u53EF\u4EE5\u5B89\u5168\u6062\u590D\u8FD0\u884C\u3002\n for (const name of [...START_ORDER].reverse().filter(name => running.includes(name))) await services[name].stop(false, false).catch(() => {});\n let programRolledBack = false;\n let rollbackError: string | undefined;\n if (rollbackPrograms) {\n context.phase(\"rollback-program\", \"\u56DE\u9000\u7A0B\u5E8F\u7248\u672C\uFF0C\u4FDD\u7559\u5F53\u524D\u73A9\u5BB6\u6570\u636E\");\n try { await restoreProgramSnapshot(context.id, rollbackPrograms); programRolledBack = true; }\n catch (failure) { rollbackError = String(failure); }\n }\n throw Object.assign(new Error(`\u7EF4\u62A4\u5931\u8D25\uFF0C\u670D\u52A1\u4FDD\u6301\u505C\u6B62\uFF1B\u5907\u4EFD\u7F16\u53F7 ${context.id}: ${error instanceof Error ? error.message : String(error)}`), { code: \"io\", details: { backupId: context.id, programRolledBack, dataRestoreRequired: Boolean(rollbackPrograms), ...(rollbackError ? { rollbackError } : {}), ...((error as { details?: object }).details ?? {}) } });\n }\n}\nexport async function launchPlatformUpdate(store: TaskStore, context: TaskContext, target: string) {\n if (isMonorepoLayout(ROOT)) throw new Error(\"\u6E90\u7801\u90E8\u7F72\u4E0D\u8986\u76D6\u5DE5\u4F5C\u533A\uFF1B\u8BF7\u4F7F\u7528\u6B63\u5E38\u5F00\u53D1\u53D1\u5E03\u6D41\u7A0B\");\n if (!/^\\d+\\.\\d+\\.\\d+$/.test(target)) throw new Error(\"\u9700\u8981\u56FA\u5B9A\u7A33\u5B9A\u7248\u672C\");\n const rows = await runtimeRows();\n if (rows.some(row => row.running && row.ownership === \"external\")) throw new Error(\"\u5916\u90E8\u670D\u52A1\u5FC5\u987B\u5148\u901A\u8FC7\u539F\u7BA1\u7406\u5668\u4F18\u96C5\u505C\u6B62\");\n const request = path.join(ROOT, \".sfmc\", \"operations\", `${context.id}.request.json`);\n const previous = readJson(path.join(ROOT, \".sfmc\", \"runtime\", \"active.json\"), { entry: fs.existsSync(path.join(ROOT, \"node_modules\", \"@sfmc-bds\", \"sfmc\", \"bin\", \"sfmc.mjs\")) ? path.join(ROOT, \"node_modules\", \"@sfmc-bds\", \"sfmc\", \"bin\", \"sfmc.mjs\") : process.env.SFMC_DAEMON_ENTRY, version: platformVersion() });\n atomicJson(request, { root: ROOT, id: context.id, target, running: rows.filter(row => row.running).map(row => row.name), previous });\n const entry = fileURLToPath(new URL(\"./platform-worker.js\", import.meta.url));\n fs.mkdirSync(path.join(ROOT, \".sfmc\", \"logs\"), { recursive: true });\n const fd = fs.openSync(path.join(ROOT, \".sfmc\", \"logs\", \"maintenance.log\"), \"a\");\n const child = spawn(process.execPath, [entry, request], { cwd: ROOT, env: { ...process.env, SFMC_ROOT: ROOT }, detached: true, windowsHide: true, stdio: [\"ignore\", fd, fd] });\n fs.closeSync(fd);\n await new Promise<void>((resolve, reject) => { child.once(\"spawn\", resolve); child.once(\"error\", reject); });\n child.unref();\n const record = store.get(context.id) as ReturnType<TaskStore[\"get\"]> & { workerPid?: number };\n record.status = \"running\"; if (child.pid) record.workerPid = child.pid;\n store.save(record);\n return { detached: true };\n}\nexport async function runPnpm(args: string[], cwd: string) {\n const script = process.env.SFMC_PNPM_ENTRY;\n if (script) return runProcess(process.execPath, [script, ...args], cwd);\n const command = process.platform === \"win32\" ? \"pnpm.cmd\" : \"pnpm\";\n const crossSpawn = require(\"cross-spawn\") as typeof spawn;\n await new Promise<void>((resolve, reject) => {\n const child = crossSpawn(command, args, { cwd, env: process.env, windowsHide: true, stdio: \"ignore\" });\n child.on(\"error\", reject); child.on(\"close\", code => code === 0 ? resolve() : reject(new Error(`pnpm \u6267\u884C\u5931\u8D25 (${code})`)));\n });\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["require", "name"]
7
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=platform-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-worker.d.ts","sourceRoot":"","sources":["../../src/management/platform-worker.ts"],"names":[],"mappings":""}