@sfmc-bds/bds-tools 0.2.0-beta.8 → 0.2.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.
Files changed (114) hide show
  1. package/LICENSE +663 -0
  2. package/README.md +1 -1
  3. package/dist/bds-manager.d.ts +16 -6
  4. package/dist/bds-manager.d.ts.map +1 -1
  5. package/dist/bds-manager.js +59 -66
  6. package/dist/bds-manager.js.map +2 -2
  7. package/dist/changelog.d.ts +11 -7
  8. package/dist/changelog.d.ts.map +1 -1
  9. package/dist/changelog.js +60 -34
  10. package/dist/changelog.js.map +2 -2
  11. package/dist/check-update.d.ts.map +1 -1
  12. package/dist/check-update.js +59 -23
  13. package/dist/check-update.js.map +2 -2
  14. package/dist/cli-pack-manager.js +11 -1
  15. package/dist/cli-pack-manager.js.map +2 -2
  16. package/dist/dependency-negotiator.d.ts +73 -0
  17. package/dist/dependency-negotiator.d.ts.map +1 -0
  18. package/dist/dependency-negotiator.js +151 -0
  19. package/dist/dependency-negotiator.js.map +7 -0
  20. package/dist/fsx.d.ts +17 -14
  21. package/dist/fsx.d.ts.map +1 -1
  22. package/dist/fsx.js +67 -19
  23. package/dist/fsx.js.map +2 -2
  24. package/dist/host-platform.d.ts +25 -0
  25. package/dist/host-platform.d.ts.map +1 -0
  26. package/dist/host-platform.js +50 -0
  27. package/dist/host-platform.js.map +7 -0
  28. package/dist/http.d.ts +49 -11
  29. package/dist/http.d.ts.map +1 -1
  30. package/dist/http.js.map +2 -2
  31. package/dist/level-dat.d.ts +105 -0
  32. package/dist/level-dat.d.ts.map +1 -0
  33. package/dist/level-dat.js +490 -0
  34. package/dist/level-dat.js.map +7 -0
  35. package/dist/pack-manager.d.ts +41 -34
  36. package/dist/pack-manager.d.ts.map +1 -1
  37. package/dist/pack-manager.js +79 -25
  38. package/dist/pack-manager.js.map +2 -2
  39. package/dist/pack-update/bindings.d.ts +16 -0
  40. package/dist/pack-update/bindings.d.ts.map +1 -0
  41. package/dist/pack-update/bindings.js +69 -0
  42. package/dist/pack-update/bindings.js.map +7 -0
  43. package/dist/pack-update/config.d.ts +16 -0
  44. package/dist/pack-update/config.d.ts.map +1 -0
  45. package/dist/pack-update/config.js +146 -0
  46. package/dist/pack-update/config.js.map +7 -0
  47. package/dist/pack-update/deps.d.ts +28 -0
  48. package/dist/pack-update/deps.d.ts.map +1 -0
  49. package/dist/pack-update/deps.js +20 -0
  50. package/dist/pack-update/deps.js.map +7 -0
  51. package/dist/pack-update/index.d.ts +55 -0
  52. package/dist/pack-update/index.d.ts.map +1 -0
  53. package/dist/pack-update/index.js +72 -0
  54. package/dist/pack-update/index.js.map +7 -0
  55. package/dist/pack-update/providers/curseforge.d.ts +23 -0
  56. package/dist/pack-update/providers/curseforge.d.ts.map +1 -0
  57. package/dist/pack-update/providers/curseforge.js +229 -0
  58. package/dist/pack-update/providers/curseforge.js.map +7 -0
  59. package/dist/pack-update/providers/index.d.ts +16 -0
  60. package/dist/pack-update/providers/index.d.ts.map +1 -0
  61. package/dist/pack-update/providers/index.js +37 -0
  62. package/dist/pack-update/providers/index.js.map +7 -0
  63. package/dist/pack-update/service.d.ts +28 -0
  64. package/dist/pack-update/service.d.ts.map +1 -0
  65. package/dist/pack-update/service.js +570 -0
  66. package/dist/pack-update/service.js.map +7 -0
  67. package/dist/pack-update/types.d.ts +126 -0
  68. package/dist/pack-update/types.d.ts.map +1 -0
  69. package/dist/pack-update/types.js +8 -0
  70. package/dist/pack-update/types.js.map +7 -0
  71. package/dist/pack-update/version-policy.d.ts +81 -0
  72. package/dist/pack-update/version-policy.d.ts.map +1 -0
  73. package/dist/pack-update/version-policy.js +210 -0
  74. package/dist/pack-update/version-policy.js.map +7 -0
  75. package/dist/paths.d.ts +1 -1
  76. package/dist/paths.d.ts.map +1 -1
  77. package/dist/paths.js +3 -5
  78. package/dist/paths.js.map +2 -2
  79. package/dist/process-probe.d.ts +34 -0
  80. package/dist/process-probe.d.ts.map +1 -0
  81. package/dist/process-probe.js +152 -0
  82. package/dist/process-probe.js.map +7 -0
  83. package/dist/qq-events-notify.d.ts +16 -0
  84. package/dist/qq-events-notify.d.ts.map +1 -0
  85. package/dist/qq-events-notify.js +70 -0
  86. package/dist/qq-events-notify.js.map +7 -0
  87. package/dist/qqutil.d.ts +10 -5
  88. package/dist/qqutil.d.ts.map +1 -1
  89. package/dist/qqutil.js +53 -10
  90. package/dist/qqutil.js.map +2 -2
  91. package/dist/rollback.d.ts.map +1 -1
  92. package/dist/rollback.js +2 -2
  93. package/dist/rollback.js.map +2 -2
  94. package/dist/server-properties-i18n.d.ts +17 -0
  95. package/dist/server-properties-i18n.d.ts.map +1 -0
  96. package/dist/server-properties-i18n.js +201 -0
  97. package/dist/server-properties-i18n.js.map +7 -0
  98. package/dist/server-properties.d.ts +25 -0
  99. package/dist/server-properties.d.ts.map +1 -1
  100. package/dist/server-properties.js +141 -1
  101. package/dist/server-properties.js.map +2 -2
  102. package/dist/types.d.ts +1 -0
  103. package/dist/types.d.ts.map +1 -1
  104. package/dist/upstream.d.ts +18 -9
  105. package/dist/upstream.d.ts.map +1 -1
  106. package/dist/upstream.js +8 -7
  107. package/dist/upstream.js.map +2 -2
  108. package/dist/version.js +2 -2
  109. package/dist/version.js.map +2 -2
  110. package/dist/world-packs.d.ts +108 -8
  111. package/dist/world-packs.d.ts.map +1 -1
  112. package/dist/world-packs.js +245 -12
  113. package/dist/world-packs.js.map +3 -3
  114. package/package.json +24 -17
@@ -1,17 +1,15 @@
1
- import {
2
- bindByteProgressToBar,
3
- createNodeServiceLogger,
4
- createTerminalProgress
5
- } from "@sfmc-bds/sdk/logs";
1
+ import { bindByteProgressToBar, createNodeServiceLogger, createTerminalProgress } from "@sfmc-bds/sdk/logs";
6
2
  import fs from "node:fs";
7
3
  import os from "node:os";
8
4
  import path from "node:path";
9
5
  import { createBdsManager } from "./bds-manager.js";
10
- import { CHANGELOG_BASE, fetchChangelog } from "./changelog.js";
11
- import { copyDirSync, emptyDirSync, hashFileAsync, rmSafe } from "./fsx.js";
6
+ import { changelogSectionUrl, fetchChangelog } from "./changelog.js";
7
+ import { copyDirSync, copyFileSyncSafe, emptyDirSync, hashFileAsync, rmSafe } from "./fsx.js";
8
+ import { bdsExePath, bdsInstallRequiredFiles, ensureBdsExecutable } from "./host-platform.js";
12
9
  import { httpDownload } from "./http.js";
13
10
  import { isMainModule } from "./is-main.js";
14
- import { loadConfig, LOG_PATH, resolvePaths } from "./paths.js";
11
+ import { loadConfig, LOG_PATH, resolvePaths, ROOT_DIR } from "./paths.js";
12
+ import { probeBdsStatus } from "./process-probe.js";
15
13
  import { sendText, sendWithImage } from "./qqutil.js";
16
14
  import {
17
15
  clearRollbackMarker,
@@ -20,7 +18,7 @@ import {
20
18
  verifyBdsInstall,
21
19
  writeRollbackMarker
22
20
  } from "./rollback.js";
23
- import { ensureEmitServerTelemetry } from "./server-properties.js";
21
+ import { ensureEmitServerTelemetry, ensureNetherNetTransport, localizeServerProperties } from "./server-properties.js";
24
22
  import { clearTaskbarProgress, isTaskbarSupported, setTaskbarProgress } from "./taskbar.js";
25
23
  import { emitUpdateKv, emitUpdateResult } from "./update-result.js";
26
24
  import {
@@ -70,7 +68,7 @@ async function doBackup(bdsPath, backupDir, preserve) {
70
68
  if (!fs.existsSync(src)) continue;
71
69
  fs.mkdirSync(path.dirname(target), { recursive: true });
72
70
  if (fs.statSync(src).isDirectory()) copyDirSync(src, target);
73
- else fs.copyFileSync(src, target);
71
+ else copyFileSyncSafe(src, target);
74
72
  anyCopied = true;
75
73
  log.info(`\u5DF2\u5907\u4EFD: ${item}`);
76
74
  }
@@ -90,7 +88,7 @@ async function restorePreserves(bdsPath, backupDir, preserve) {
90
88
  copyDirSync(src, dest);
91
89
  } else {
92
90
  fs.mkdirSync(path.dirname(dest), { recursive: true });
93
- fs.copyFileSync(src, dest);
91
+ copyFileSyncSafe(src, dest);
94
92
  }
95
93
  log.info(`\u5DF2\u6062\u590D: ${item}`);
96
94
  } catch (e) {
@@ -98,6 +96,17 @@ async function restorePreserves(bdsPath, backupDir, preserve) {
98
96
  }
99
97
  }
100
98
  }
99
+ async function waitForBdsStopped(timeoutMs = 1e4) {
100
+ const deadline = Date.now() + timeoutMs;
101
+ let status = await probeBdsStatus({ rootDir: ROOT_DIR });
102
+ while (status.state !== "stopped" && Date.now() < deadline) {
103
+ await new Promise((resolve) => setTimeout(resolve, 250));
104
+ status = await probeBdsStatus({ rootDir: ROOT_DIR });
105
+ }
106
+ if (status.state !== "stopped") {
107
+ throw new Error(`BDS \u8FDB\u7A0B ${status.pid} \u4ECD\u5728\u8FD0\u884C\uFF0C\u5DF2\u53D6\u6D88\u6587\u4EF6\u8986\u76D6`);
108
+ }
109
+ }
101
110
  async function extractZipToBds(zipPath, destDir) {
102
111
  const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "bds-extract-"));
103
112
  try {
@@ -123,7 +132,7 @@ async function runUpdate() {
123
132
  log.info(`===== \u5F00\u59CB\u68C0\u67E5\u66F4\u65B0 (${channel}) =====`);
124
133
  fs.mkdirSync(bdsPath, { recursive: true });
125
134
  fs.mkdirSync(backupDir, { recursive: true });
126
- const exePath = path.join(bdsPath, "bedrock_server.exe");
135
+ const exePath = bdsExePath(bdsPath);
127
136
  const currentVer = await getCurrentVersionAsync(exePath).catch(() => getCurrentVersionSync(exePath));
128
137
  log.info(`\u5F53\u524D\u7248\u672C: ${currentVer}`);
129
138
  let latestVer;
@@ -194,17 +203,17 @@ async function runUpdate() {
194
203
 
195
204
  \u670D\u52A1\u5668\u5373\u5C06\u5F00\u59CB\u66F4\u65B0~ \u8BF7\u8010\u5FC3\u7B49\u5F85^(*\uFFE3(oo)\uFFE3)^`
196
205
  );
197
- const cl = await fetchChangelog(channel);
206
+ const cl = await fetchChangelog(channel, latestVer);
198
207
  if (cl) {
199
- const text = `\u{1F4CB} \u66F4\u65B0\u5185\u5BB9\u6982\u8981
208
+ const text = `\u{1F4CB} ${latestVer} \u66F4\u65B0\u5185\u5BB9\u6982\u8981
200
209
 
201
210
  ${cl.text.slice(0, 1500)}
202
211
 
203
- \u5B8C\u6574\u65E5\u5FD7: ${CHANGELOG_BASE}`;
212
+ \u5B8C\u6574\u65E5\u5FD7: ${cl.url}`;
204
213
  if (cl.imageBase64) await sendWithImage(text, cl.imageBase64);
205
214
  else await sendText(text);
206
215
  } else {
207
- await sendText(`\u{1F4CB} \u66F4\u65B0\u65E5\u5FD7: ${CHANGELOG_BASE}`);
216
+ await sendText(`\u{1F4CB} ${latestVer} \u66F4\u65B0\u65E5\u5FD7\u76EE\u5F55: ${changelogSectionUrl(channel)}`);
208
217
  }
209
218
  }
210
219
  let backupInfo;
@@ -236,9 +245,16 @@ ${cl.text.slice(0, 1500)}
236
245
  try {
237
246
  log.info("\u505C\u6B62 BDS \u670D\u52A1...");
238
247
  await bds.stop();
248
+ await waitForBdsStopped();
239
249
  log.info("BDS \u5DF2\u505C\u6B62");
240
250
  } catch (e) {
241
- log.warn(`BDS \u505C\u6B62\u5F02\u5E38: ${e.message}`);
251
+ log.error(`BDS \u505C\u6B62\u5931\u8D25: ${e.message}`);
252
+ await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25
253
+
254
+ \u505C\u670D\u5931\u8D25: ${e.message}
255
+ \u64CD\u4F5C\u5DF2\u4E2D\u6B62`);
256
+ clearRollbackMarker();
257
+ return 1;
242
258
  }
243
259
  const stagingDir = fs.mkdtempSync(path.join(os.tmpdir(), "bds-update-"));
244
260
  const zipPath = path.join(stagingDir, `bedrock-server-${latestVer}.zip`);
@@ -254,7 +270,7 @@ ${cl.text.slice(0, 1500)}
254
270
  for (const url of downloadUrls) {
255
271
  const progressBar = createTerminalProgress({
256
272
  stream: process.stderr,
257
- logger: (msg) => log.info(msg.startsWith("\u8FDB\u5EA6") ? `\u4E0B\u8F7D${msg.slice(2)}` : msg),
273
+ logger: (msg) => log.info(msg),
258
274
  format: "\u4E0B\u8F7D\u8FDB\u5EA6 | {bar} | {percentage}% | {value}/{total} MB | \u901F\u5EA6: {speed}"
259
275
  });
260
276
  const onByteProgress = bindByteProgressToBar(progressBar, {
@@ -311,13 +327,35 @@ BDS \u5DF2\u505C\u6B62\uFF0C\u8BF7\u624B\u52A8\u6062\u590D`);
311
327
  rmSafe(stagingDir);
312
328
  return 1;
313
329
  }
330
+ try {
331
+ await waitForBdsStopped();
332
+ } catch (e) {
333
+ log.error(`\u90E8\u7F72\u5DF2\u4E2D\u6B62: ${e.message}`);
334
+ await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25
335
+
336
+ ${e.message}
337
+ \u5C1A\u672A\u8986\u76D6\u5B89\u88C5\u76EE\u5F55`);
338
+ rmSafe(stagingDir);
339
+ clearRollbackMarker();
340
+ return 1;
341
+ }
314
342
  try {
315
343
  log.info("\u89E3\u538B\u4E2D...");
316
344
  emptyDirSync(bdsPath);
317
345
  await extractZipToBds(zipPath, bdsPath);
346
+ ensureBdsExecutable(exePath);
318
347
  log.info("\u89E3\u538B\u5B8C\u6210");
319
348
  } catch (e) {
320
349
  log.error(`\u89E3\u538B\u5931\u8D25: ${e.message}`);
350
+ const status = await probeBdsStatus({ rootDir: ROOT_DIR });
351
+ if (status.state !== "stopped") {
352
+ await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25
353
+
354
+ \u89E3\u538B\u5931\u8D25: ${e.message}
355
+ BDS \u4ECD\u5728\u8FD0\u884C\uFF0C\u8BF7\u5148\u505C\u670D\u5E76\u624B\u52A8\u6062\u590D`);
356
+ rmSafe(stagingDir);
357
+ return 1;
358
+ }
321
359
  await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25
322
360
 
323
361
  \u89E3\u538B\u5931\u8D25: ${e.message}
@@ -329,11 +367,7 @@ BDS \u5DF2\u505C\u6B62\uFF0C\u8BF7\u624B\u52A8\u6062\u590D`);
329
367
  } finally {
330
368
  rmSafe(zipPath);
331
369
  }
332
- const verify = verifyBdsInstall(bdsPath, [
333
- "bedrock_server.exe",
334
- /*"bedrock_server_symbols.debug",*/
335
- "permissions.json"
336
- ]);
370
+ const verify = verifyBdsInstall(bdsPath, bdsInstallRequiredFiles());
337
371
  if (!verify.ok) {
338
372
  log.error(`\u89E3\u538B\u540E\u7684 BDS \u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5931\u6587\u4EF6: ${verify.missing.join(", ")}`);
339
373
  await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25
@@ -346,6 +380,8 @@ BDS \u5DF2\u505C\u6B62\uFF0C\u8BF7\u624B\u52A8\u6062\u590D`);
346
380
  }
347
381
  await restorePreserves(bdsPath, backupInfo.path, preserve);
348
382
  ensureEmitServerTelemetry(bdsPath, log);
383
+ ensureNetherNetTransport(bdsPath, log);
384
+ localizeServerProperties(bdsPath, { logger: log, rootDir: ROOT_DIR });
349
385
  const newExeHash = await hashFileAsync(exePath, "sha256").catch(() => "");
350
386
  if (newExeHash) {
351
387
  saveVersionCache(latestVer, newExeHash);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/check-update.ts"],
4
- "sourcesContent": ["/**\n * check-update.ts \u2014 BDS \u81EA\u52A8\u66F4\u65B0\u5668 (\u4E3B\u6D41\u7A0B)\n *\n * 1. \u4E34\u65F6 staging \u76EE\u5F55 (mkdtempSync) - \u907F\u514D\u6C61\u67D3\u6570\u636E\u6839\n * 2. \u4E0B\u8F7D/\u89E3\u538B\u5931\u8D25 \u2192 \u81EA\u52A8\u4ECE\u5907\u4EFD\u56DE\u6EDA preserves\n * 3. \u6D41\u5F0F SHA256 \u6821\u9A8C - \u4E0D\u628A 250MB \u6587\u4EF6\u8BFB\u5165\u5185\u5B58\n * 4. \u517C\u5BB9\u7248\u672C\u767D\u540D\u5355 - \u4E0D\u5339\u914D\u5219\u8DF3\u8FC7\u5347\u7EA7\n * 5. QQ \u901A\u77E5\u7EDF\u4E00\u52A0 5s \u8D85\u65F6 - \u6C38\u8FDC\u4E0D\u963B\u585E\u4E3B\u6D41\u7A0B\n * 6. Rollback marker \u843D\u76D8\u5230 <ROOT>/.sfmc/ - \u8DE8\u8FDB\u7A0B / \u8DE8\u91CD\u542F\u53EF\u6062\u590D\n */\n\nimport {\n bindByteProgressToBar,\n createNodeServiceLogger,\n createTerminalProgress,\n} from \"@sfmc-bds/sdk/logs\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { createBdsManager } from \"./bds-manager.js\";\nimport { CHANGELOG_BASE, fetchChangelog } from \"./changelog.js\";\nimport { copyDirSync, emptyDirSync, hashFileAsync, rmSafe } from \"./fsx.js\";\nimport { httpDownload } from \"./http.js\";\nimport { isMainModule } from \"./is-main.js\";\nimport { loadConfig, LOG_PATH, resolvePaths } from \"./paths.js\";\nimport { sendText, sendWithImage } from \"./qqutil.js\";\nimport {\n clearRollbackMarker,\n getDirSize,\n rollbackFromBackup,\n verifyBdsInstall,\n writeRollbackMarker,\n} from \"./rollback.js\";\nimport { ensureEmitServerTelemetry } from \"./server-properties.js\";\nimport { clearTaskbarProgress, isTaskbarSupported, setTaskbarProgress } from \"./taskbar.js\";\nimport { emitUpdateKv, emitUpdateResult } from \"./update-result.js\";\nimport {\n buildDownloadUrls,\n fetchVersionDetails,\n getVersionInfo,\n isVersionCompatible,\n verifyFileHash,\n} from \"./upstream.js\";\nimport { compareVersions, getCurrentVersionAsync, getCurrentVersionSync, saveVersionCache } from \"./version.js\";\nimport { extractZipFileToDir } from \"./zipx.js\";\n\n// \u72EC\u7ACB\u5165\u53E3:source = \"updater\",\u4E0E bds-manager \u7684 \"bds-tools\" \u533A\u5206;\u540C\u843D\u76D8 bds-update.log\nconst log = createNodeServiceLogger({ source: \"updater\", logPath: LOG_PATH });\nconst closeLog = (): void => log.close();\n\nfunction parseArgs(argv: string[]): Record<string, string | boolean> {\n const out: Record<string, string | boolean> = {};\n for (const a of argv) {\n const m = a.match(/^--([\\w-]+)(?:=(.+))?$/);\n if (m) out[m[1]!] = m[2] || true;\n }\n return out;\n}\n\ninterface UpdateContext {\n cfg: ReturnType<typeof loadConfig>;\n channel: \"release\" | \"preview\" | string;\n checkOnly: boolean;\n force: boolean;\n bdsPath: string;\n backupDir: string;\n preserve: string[];\n autoRestart: boolean;\n qqNotify: boolean;\n}\n\nfunction buildContext(): UpdateContext {\n const cfg = loadConfig();\n const args = parseArgs(process.argv.slice(2));\n const { bds_path, backup_dir, preserve } = resolvePaths(cfg);\n const channel = String(args[\"channel\"] || cfg.channel || \"release\");\n return {\n cfg,\n channel,\n checkOnly: !!args[\"check-only\"],\n force: !!args[\"force\"],\n bdsPath: bds_path,\n backupDir: backup_dir,\n preserve,\n autoRestart: !args[\"no-start\"] && cfg.auto_restart !== false,\n qqNotify: !!cfg.qq_notify,\n };\n}\n\nasync function doBackup(\n bdsPath: string,\n backupDir: string,\n preserve: string[]\n): Promise<{ path: string; size: number }> {\n const dateStr = new Date().toISOString().slice(0, 10);\n const dest = path.join(backupDir, dateStr);\n fs.mkdirSync(dest, { recursive: true });\n\n let anyCopied = false;\n for (const item of preserve) {\n const src = path.join(bdsPath, item);\n const target = path.join(dest, item);\n if (!fs.existsSync(src)) continue;\n fs.mkdirSync(path.dirname(target), { recursive: true });\n if (fs.statSync(src).isDirectory()) copyDirSync(src, target);\n else fs.copyFileSync(src, target);\n anyCopied = true;\n log.info(`\u5DF2\u5907\u4EFD: ${item}`);\n }\n\n // \u5373\u4F7F\u5168\u90E8 preserve \u90FD\u8DF3\u8FC7\uFF0C\u4E5F\u8BA9\u76EE\u5F55\u5B58\u5728\u4EE5\u4FBF\u8BB0\u5F55\u65F6\u95F4\u6233\n if (!anyCopied) {\n log.info(`\u6CA1\u6709\u9700\u8981\u5907\u4EFD\u7684\u6587\u4EF6 (preserve \u5217\u8868\u4E3A\u7A7A\u6216\u5168\u90E8\u7F3A\u5931)`);\n }\n return { path: dest, size: getDirSize(dest) };\n}\n\n/** \u5F02\u6B65\u6062\u590D preserves \u4ECE\u5907\u4EFD\u5230 BDS \u8DEF\u5F84 */\nasync function restorePreserves(bdsPath: string, backupDir: string, preserve: string[]): Promise<void> {\n for (const item of preserve) {\n const src = path.join(backupDir, item);\n const dest = path.join(bdsPath, item);\n if (!fs.existsSync(src)) continue;\n try {\n if (fs.statSync(src).isDirectory()) {\n if (fs.existsSync(dest)) emptyDirSync(dest);\n copyDirSync(src, dest);\n } else {\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n fs.copyFileSync(src, dest);\n }\n log.info(`\u5DF2\u6062\u590D: ${item}`);\n } catch (e) {\n log.warn(`\u6062\u590D\u5931\u8D25 ${item}: ${(e as Error).message}`);\n }\n }\n}\n\n/** \u628A zip \u89E3\u538B\u5230 destDir (\u8986\u76D6) \u2014 \u7ECF zipx \u5B89\u5168\u89E3\u538B */\nasync function extractZipToBds(zipPath: string, destDir: string): Promise<void> {\n // \u62BD\u51FA\u5230\u4E34\u65F6\u76EE\u5F55\uFF0C\u907F\u514D\u65E7\u5185\u5BB9\u5E72\u6270\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"bds-extract-\"));\n try {\n await extractZipFileToDir(zipPath, tmpDir);\n // \u628A\u4E34\u65F6\u76EE\u5F55\u91CC\u7684\u5185\u5BB9\u590D\u5236\u5230 BDS \u8DEF\u5F84\n for (const entry of fs.readdirSync(tmpDir)) {\n const srcPath = path.join(tmpDir, entry);\n const destPath = path.join(destDir, entry);\n if (fs.statSync(srcPath).isDirectory()) {\n if (fs.existsSync(destPath)) emptyDirSync(destPath);\n copyDirSync(srcPath, destPath);\n } else {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n } finally {\n rmSafe(tmpDir);\n }\n}\n\nexport async function runUpdate(): Promise<number> {\n const startTime = Date.now();\n const ctx = buildContext();\n const { cfg, channel, checkOnly, force, bdsPath, backupDir, preserve, autoRestart, qqNotify } = ctx;\n\n log.info(`===== \u5F00\u59CB\u68C0\u67E5\u66F4\u65B0 (${channel}) =====`);\n fs.mkdirSync(bdsPath, { recursive: true });\n fs.mkdirSync(backupDir, { recursive: true });\n\n // 1. \u5F53\u524D\u7248\u672C\n const exePath = path.join(bdsPath, \"bedrock_server.exe\");\n const currentVer = await getCurrentVersionAsync(exePath).catch(() => getCurrentVersionSync(exePath));\n log.info(`\u5F53\u524D\u7248\u672C: ${currentVer}`);\n\n // 2. \u83B7\u53D6\u6700\u65B0\u7248\u672C\n let latestVer: string;\n try {\n const info = await getVersionInfo(cfg, channel);\n latestVer = info.version;\n log.info(`\u6700\u65B0\u7248\u672C: ${latestVer}`);\n const cmp = compareVersions(latestVer, currentVer);\n if (cmp <= 0 && !force) {\n log.info(\"\u5DF2\u662F\u6700\u65B0\u7248\u672C\uFF0C\u65E0\u9700\u66F4\u65B0\");\n if (qqNotify) {\n await sendText(`\u2705 BDS \u5DF2\u662F\u6700\u65B0\u7248\u672C\\n\\n\u5F53\u524D: ${currentVer}\\n\u6700\u65B0: ${latestVer}`);\n }\n emitUpdateKv(\"CURRENT\", currentVer, log);\n emitUpdateKv(\"LATEST\", latestVer, log);\n emitUpdateResult(\"uptodate\", log);\n return 0;\n }\n } catch (e) {\n log.error(`\u83B7\u53D6\u7248\u672C\u4FE1\u606F\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u65E0\u6CD5\u83B7\u53D6\u7248\u672C\u4FE1\u606F: ${(e as Error).message}`);\n return 1;\n }\n\n // \u517C\u5BB9\u6027\u68C0\u67E5\n if (!force && !isVersionCompatible(cfg, latestVer)) {\n log.warn(`${latestVer} \u4E0D\u5728\u517C\u5BB9\u7248\u672C\u767D\u540D\u5355\u4E2D\uFF0C\u8DF3\u8FC7\u5347\u7EA7`);\n if (qqNotify) {\n await sendText(`\u26A0\uFE0F BDS ${latestVer} \u4E0D\u5728\u517C\u5BB9\u6027\u767D\u540D\u5355\uFF0C\u5DF2\u8DF3\u8FC7\u5347\u7EA7\u3002\u8BF7\u4EBA\u5DE5\u786E\u8BA4\u3002`);\n }\n emitUpdateResult(\"skipped\", log);\n return 2;\n }\n\n // 3. \u53D6\u4E0B\u8F7D\u94FE\u63A5\n let downloadUrls: string[];\n let hash: { sha1: string; sha256: string };\n try {\n const details = await fetchVersionDetails(cfg, channel, latestVer);\n downloadUrls = buildDownloadUrls(cfg, channel, latestVer, details);\n hash = { sha1: details.sha1, sha256: details.sha256 };\n } catch (e) {\n log.error(`\u83B7\u53D6\u4E0B\u8F7D\u8BE6\u60C5\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u4E0B\u8F7D\u8BE6\u60C5\u83B7\u53D6\u5931\u8D25: ${(e as Error).message}`);\n return 1;\n }\n\n if (checkOnly) {\n emitUpdateKv(\"CURRENT\", currentVer, log);\n emitUpdateKv(\"LATEST\", latestVer, log);\n emitUpdateKv(\"CHANNEL\", channel, log);\n emitUpdateKv(\"URLS\", String(downloadUrls.length), log);\n emitUpdateResult(\"check-only\", log);\n return 0;\n }\n\n log.info(`\u53D1\u73B0\u65B0\u7248\u672C: ${currentVer} \u2192 ${latestVer}`);\n\n // 4. QQ \u9884\u544A\n if (qqNotify) {\n await sendText(\n `\uD835\uDC0C\uD835\uDC22\uD835\uDC27\uD835\uDC1E\uD835\uDC1C\uD835\uDC2B\uD835\uDC1A\uD835\uDC1F\uD835\uDC2D \uD835\uDC01\uD835\uDC03\uD835\uDC12 \u66F4\u65B0\u901A\u77E5\\n\\n` +\n `\u68C0\u6D4B\u5230\u65B0\u7248\u672C\uFF01\\n\\n` +\n `\u5F53\u524D: ${currentVer}\\n` +\n `\u6700\u65B0: ${latestVer}\\n` +\n `\u9891\u9053: ${channel === \"preview\" ? \"\u9884\u89C8\u7248\" : \"\u6B63\u5F0F\u7248\"}\\n\\n` +\n `\u670D\u52A1\u5668\u5373\u5C06\u5F00\u59CB\u66F4\u65B0~ \u8BF7\u8010\u5FC3\u7B49\u5F85^(*\uFFE3(oo)\uFFE3)^`\n );\n const cl = await fetchChangelog(channel);\n if (cl) {\n const text = `\uD83D\uDCCB \u66F4\u65B0\u5185\u5BB9\u6982\u8981\\n\\n${cl.text.slice(0, 1500)}\\n\\n\u5B8C\u6574\u65E5\u5FD7: ${CHANGELOG_BASE}`;\n if (cl.imageBase64) await sendWithImage(text, cl.imageBase64);\n else await sendText(text);\n } else {\n await sendText(`\uD83D\uDCCB \u66F4\u65B0\u65E5\u5FD7: ${CHANGELOG_BASE}`);\n }\n }\n\n // 5. \u5907\u4EFD\n let backupInfo: { path: string; size: number };\n try {\n backupInfo = await doBackup(bdsPath, backupDir, preserve);\n log.info(`\u5907\u4EFD\u5B8C\u6210: ${backupInfo.path} (${(backupInfo.size / 1024 / 1024).toFixed(1)} MB)`);\n if (qqNotify) {\n await sendText(`\u2705 \u5907\u4EFD\u5B8C\u6210\\n\\n\u5927\u5C0F: ${(backupInfo.size / 1024 / 1024).toFixed(1)} MB\\n\u4F4D\u7F6E: ${backupInfo.path}`);\n }\n } catch (e) {\n log.error(`\u5907\u4EFD\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u5907\u4EFD\u5931\u8D25: ${(e as Error).message}\\n\u64CD\u4F5C\u5DF2\u4E2D\u6B62`);\n return 1;\n }\n\n // 6. \u5199\u56DE\u6EDA\u6807\u8BB0 (\u8DE8\u8FDB\u7A0B\u53EF\u6062\u590D)\n writeRollbackMarker({\n timestamp: Date.now(),\n bds_path: bdsPath,\n backup_dir: backupInfo.path,\n preserve,\n previous_version: currentVer,\n });\n\n // 7. \u505C\u670D\n const bds = createBdsManager({ detached: true });\n try {\n log.info(\"\u505C\u6B62 BDS \u670D\u52A1...\");\n await bds.stop();\n log.info(\"BDS \u5DF2\u505C\u6B62\");\n } catch (e) {\n log.warn(`BDS \u505C\u6B62\u5F02\u5E38: ${(e as Error).message}`);\n }\n\n // 8. \u4E0B\u8F7D (\u5168\u90E8\u5931\u8D25\u5219\u56DE\u6EDA)\n // \u7528 mkdtempSync \u521B\u5EFA\u4E34\u65F6 staging \u76EE\u5F55 - \u907F\u514D\u6C61\u67D3 SCRIPT_DIR\n const stagingDir = fs.mkdtempSync(path.join(os.tmpdir(), \"bds-update-\"));\n const zipPath = path.join(stagingDir, `bedrock-server-${latestVer}.zip`);\n let downloaded = false;\n try {\n log.info(`\u5F00\u59CB\u4E0B\u8F7D ${latestVer}...`);\n if (qqNotify) await sendText(`\uD83D\uDCE5 \u6B63\u5728\u4E0B\u8F7D BDS ${latestVer}...`);\n\n let lastErr: Error | null = null;\n const downloadTimeoutMs = (cfg.download_timeout ?? 120) * 1000;\n /* stderr \u88AB pipe \u65F6\u4E0D\u753B bar\uFF1B\u7528\u6587\u672C\u8FDB\u5EA6\u7ED9 sfmc REPL \u7B49\u7236\u8FDB\u7A0B */\n if (isTaskbarSupported() && process.stdout.isTTY) {\n log.info(\"\u68C0\u6D4B\u5230 Windows Terminal,\u4EFB\u52A1\u680F\u8FDB\u5EA6\u5DF2\u542F\u7528 (OSC 9;4)\");\n }\n for (const url of downloadUrls) {\n /* \u6BCF\u6B21\u5C1D\u8BD5\u65B0\u5EFA bar + binder\uFF0C\u907F\u514D\u5931\u8D25\u91CD\u8BD5\u65F6 started \u72B6\u6001\u6B8B\u7559\uFF08LSP\uFF09 */\n const progressBar = createTerminalProgress({\n stream: process.stderr,\n logger: (msg) => log.info(msg.startsWith(\"\u8FDB\u5EA6\") ? `\u4E0B\u8F7D${msg.slice(2)}` : msg),\n format: \"\u4E0B\u8F7D\u8FDB\u5EA6 | {bar} | {percentage}% | {value}/{total} MB | \u901F\u5EA6: {speed}\",\n });\n const onByteProgress = bindByteProgressToBar(progressBar, {\n speedSampleMs: 0,\n onProgress: (dl, total) => {\n const pct = total > 0 ? (dl / total) * 100 : 0;\n setTaskbarProgress(pct);\n },\n });\n try {\n setTaskbarProgress(0);\n await httpDownload(url, zipPath, {\n totalTimeoutMs: Math.max(downloadTimeoutMs, 600_000), // \u4E0D\u5C11\u4E8E 10 \u5206\u949F\n onProgress: onByteProgress,\n });\n if (progressBar.active) progressBar.stop();\n // \u4E0B\u8F7D\u5B8C\u6210,\u4EFB\u52A1\u680F\u6536\u5230 100% \u7EFF\u6761\u540E\u6E05\u6389\n setTaskbarProgress(100);\n clearTaskbarProgress();\n downloaded = true;\n lastErr = null;\n break;\n } catch (e) {\n if (progressBar.active) progressBar.stop();\n // \u4E0B\u8F7D\u5931\u8D25,\u4EFB\u52A1\u680F\u4EAE\u7EA2\n setTaskbarProgress(100, \"error\");\n clearTaskbarProgress();\n lastErr = e as Error;\n log.warn(`${url} \u4E0D\u53EF\u7528: ${lastErr.message}\uFF0C\u5C1D\u8BD5\u5907\u7528\u5730\u5740...`);\n }\n }\n if (!downloaded && lastErr) throw lastErr;\n\n const zipSizeMB = (fs.statSync(zipPath).size / 1024 / 1024).toFixed(1);\n log.info(`\u4E0B\u8F7D\u5B8C\u6210 (${zipSizeMB} MB)`);\n\n // \u6D41\u5F0F\u54C8\u5E0C\u6821\u9A8C\n if (hash.sha1 || hash.sha256) {\n const algo = hash.sha256 ? \"SHA256\" : \"SHA1\";\n log.info(`\u6821\u9A8C\u6587\u4EF6\u5B8C\u6574\u6027 (${algo})...`);\n const ok = await verifyFileHash(zipPath, hash.sha1, hash.sha256);\n if (!ok) throw new Error(`${algo} \u6821\u9A8C\u4E0D\u901A\u8FC7\uFF0C\u6587\u4EF6\u53EF\u80FD\u635F\u574F`);\n log.info(`${algo} \u6821\u9A8C\u901A\u8FC7`);\n }\n } catch (e) {\n log.error(`\u4E0B\u8F7D\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u4E0B\u8F7D\u5931\u8D25: ${(e as Error).message}\\nBDS \u5DF2\u505C\u6B62\uFF0C\u8BF7\u624B\u52A8\u6062\u590D`);\n // \u81EA\u52A8\u56DE\u6EDA\n rollbackFromBackup({\n timestamp: Date.now(),\n bds_path: bdsPath,\n backup_dir: backupInfo.path,\n preserve,\n previous_version: currentVer,\n });\n rmSafe(stagingDir);\n return 1;\n }\n\n // 9. \u89E3\u538B + \u90E8\u7F72\n try {\n log.info(\"\u89E3\u538B\u4E2D...\");\n // \u5148\u6E05\u7A7A BDS \u76EE\u5F55\n emptyDirSync(bdsPath);\n await extractZipToBds(zipPath, bdsPath);\n log.info(\"\u89E3\u538B\u5B8C\u6210\");\n } catch (e) {\n log.error(`\u89E3\u538B\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u89E3\u538B\u5931\u8D25: ${(e as Error).message}\\nBDS \u5DF2\u505C\u6B62\uFF0C\u8BF7\u624B\u52A8\u6062\u590D`);\n // \u56DE\u6EDA: \u6E05\u7A7A + \u4ECE\u5907\u4EFD\u6062\u590D preserves\n emptyDirSync(bdsPath);\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n rmSafe(stagingDir);\n return 1;\n } finally {\n rmSafe(zipPath); // \u6E05\u6389 staging zip\n }\n\n // 10. \u5B8C\u6574\u6027\u68C0\u67E5 (\u907F\u514D\u89E3\u538B\u51FA\u7A7A/\u7F3A\u6587\u4EF6\u7684\u75C5\u6001\u5305)\n const verify = verifyBdsInstall(bdsPath, [\n \"bedrock_server.exe\",\n /*\"bedrock_server_symbols.debug\",*/ \"permissions.json\",\n ]);\n if (!verify.ok) {\n log.error(`\u89E3\u538B\u540E\u7684 BDS \u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5931\u6587\u4EF6: ${verify.missing.join(\", \")}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u90E8\u7F72\u540E\u7F3A\u5931\u5173\u952E\u6587\u4EF6: ${verify.missing.join(\", \")}`);\n emptyDirSync(bdsPath);\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n rmSafe(stagingDir);\n return 1;\n }\n\n // 11. \u6062\u590D preserves (zip \u89E3\u538B\u65F6\u8FD9\u4E9B\u76EE\u5F55\u53EF\u80FD\u88AB\u8986\u76D6)\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n\n // 11b. \u5B89\u88C5\u6536\u5C3E\uFF1A\u56E0 EULA \u5DF2\u540C\u610F\uFF0C\u786E\u4FDD\u9065\u6D4B\u5F00\u5173\uFF08\u5DF2\u6709\u5219\u8DF3\u8FC7\uFF09\n ensureEmitServerTelemetry(bdsPath, log);\n\n // 12. \u5199\u5165\u7248\u672C\u7F13\u5B58\n const newExeHash = await hashFileAsync(exePath, \"sha256\").catch(() => \"\");\n if (newExeHash) {\n saveVersionCache(latestVer, newExeHash);\n log.info(`\u5DF2\u8BB0\u5F55\u7248\u672C ${latestVer} \u7684 SHA256`);\n }\n\n // 13. \u542F\u52A8 BDS\n if (autoRestart) {\n try {\n log.info(\"\u542F\u52A8 BDS...\");\n await bds.start();\n } catch (e) {\n log.error(`\u542F\u52A8\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u542F\u52A8\u5931\u8D25: ${(e as Error).message}\\n\u8BF7\u624B\u52A8\u542F\u52A8 BDS`);\n // \u6CE8\u610F: \u6B64\u65F6 BDS \u5DF2\u7ECF\u90E8\u7F72\u5B8C\u6210\uFF0C\u542F\u52A8\u5931\u8D25 \u2192 \u542F\u52A8\u95EE\u9898\uFF0C\u4E0D\u505A\u6587\u4EF6\u7EA7\u56DE\u6EDA\n rmSafe(stagingDir);\n clearRollbackMarker();\n return 1;\n }\n }\n\n rmSafe(stagingDir);\n clearRollbackMarker();\n\n // 14. QQ \u901A\u77E5\u7ED3\u679C\n const durationMs = Date.now() - startTime;\n if (qqNotify) {\n await sendText(\n `\u2705 BDS \u66F4\u65B0\u5B8C\u6210\\n\\n` +\n `${currentVer} \u2192 ${latestVer}\\n` +\n `\u8017\u65F6: ${(durationMs / 1000).toFixed(1)}s\\n` +\n `${autoRestart ? \"\u670D\u52A1\u5668\u5DF2\u91CD\u65B0\u542F\u52A8\" : \"\u8BF7\u624B\u52A8\u91CD\u542F\u670D\u52A1\u5668\"}`\n );\n }\n log.info(`===== \u66F4\u65B0\u5B8C\u6210 (${(durationMs / 1000).toFixed(1)}s) =====`);\n /* \u673A\u5668\u53EF\u8BFB\u7ED3\u679C\u6807\u8BB0\uFF1A\u4F9B sfmc \u7B49\u76D1\u7763\u5668\u5224\u65AD\u300C\u771F\u6B63\u5B8C\u6210\u90E8\u7F72\u300D\uFF0C\u52FF\u4F9D\u8D56\u672C\u5730\u5316\u65E5\u5FD7\u6587\u6848\u3002 */\n emitUpdateResult(\"deployed\", log);\n return 0;\n}\n\nfunction isMain(): boolean {\n // sfmc supervisor \u901A\u8FC7 SFMC_SERVICE \u62C9\u8D77\u5B50\u8FDB\u7A0B\u65F6\u4F18\u5148\u5224\u5B9A\n if (process.env.SFMC_SERVICE === \"update\") return true;\n return isMainModule(import.meta.url);\n}\n\nif (isMain()) {\n runUpdate()\n .then((code) => {\n closeLog();\n process.exit(code);\n })\n .catch((e) => {\n log.error(`\u672A\u6355\u83B7\u9519\u8BEF: ${(e as Error).message}`);\n closeLog();\n process.exit(1);\n });\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * check-update.ts \u2014 BDS \u81EA\u52A8\u66F4\u65B0\u5668 (\u4E3B\u6D41\u7A0B)\n *\n * 1. \u4E34\u65F6 staging \u76EE\u5F55 (mkdtempSync) - \u907F\u514D\u6C61\u67D3\u6570\u636E\u6839\n * 2. \u4E0B\u8F7D/\u89E3\u538B\u5931\u8D25 \u2192 \u81EA\u52A8\u4ECE\u5907\u4EFD\u56DE\u6EDA preserves\n * 3. \u6D41\u5F0F SHA256 \u6821\u9A8C - \u4E0D\u628A 250MB \u6587\u4EF6\u8BFB\u5165\u5185\u5B58\n * 4. \u517C\u5BB9\u7248\u672C\u767D\u540D\u5355 - \u4E0D\u5339\u914D\u5219\u8DF3\u8FC7\u5347\u7EA7\n * 5. QQ \u901A\u77E5\u7EDF\u4E00\u52A0 5s \u8D85\u65F6 - \u6C38\u8FDC\u4E0D\u963B\u585E\u4E3B\u6D41\u7A0B\n * 6. Rollback marker \u843D\u76D8\u5230 <ROOT>/.sfmc/ - \u8DE8\u8FDB\u7A0B / \u8DE8\u91CD\u542F\u53EF\u6062\u590D\n */\n\nimport { bindByteProgressToBar, createNodeServiceLogger, createTerminalProgress } from \"@sfmc-bds/sdk/logs\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { createBdsManager } from \"./bds-manager.js\";\nimport { changelogSectionUrl, fetchChangelog } from \"./changelog.js\";\nimport { copyDirSync, copyFileSyncSafe, emptyDirSync, hashFileAsync, rmSafe } from \"./fsx.js\";\nimport { bdsExePath, bdsInstallRequiredFiles, ensureBdsExecutable } from \"./host-platform.js\";\nimport { httpDownload } from \"./http.js\";\nimport { isMainModule } from \"./is-main.js\";\nimport { loadConfig, LOG_PATH, resolvePaths, ROOT_DIR } from \"./paths.js\";\nimport { probeBdsStatus } from \"./process-probe.js\";\nimport { sendText, sendWithImage } from \"./qqutil.js\";\nimport {\n clearRollbackMarker,\n getDirSize,\n rollbackFromBackup,\n verifyBdsInstall,\n writeRollbackMarker,\n} from \"./rollback.js\";\nimport { ensureEmitServerTelemetry, ensureNetherNetTransport, localizeServerProperties } from \"./server-properties.js\";\nimport { clearTaskbarProgress, isTaskbarSupported, setTaskbarProgress } from \"./taskbar.js\";\nimport { emitUpdateKv, emitUpdateResult } from \"./update-result.js\";\nimport {\n buildDownloadUrls,\n fetchVersionDetails,\n getVersionInfo,\n isVersionCompatible,\n verifyFileHash,\n} from \"./upstream.js\";\nimport { compareVersions, getCurrentVersionAsync, getCurrentVersionSync, saveVersionCache } from \"./version.js\";\nimport { extractZipFileToDir } from \"./zipx.js\";\n\n// \u72EC\u7ACB\u5165\u53E3:source = \"updater\",\u4E0E bds-manager \u7684 \"bds-tools\" \u533A\u5206;\u540C\u843D\u76D8 bds-update.log\nconst log = createNodeServiceLogger({ source: \"updater\", logPath: LOG_PATH });\nconst closeLog = (): void => log.close();\n\nfunction parseArgs(argv: string[]): Record<string, string | boolean> {\n const out: Record<string, string | boolean> = {};\n for (const a of argv) {\n const m = a.match(/^--([\\w-]+)(?:=(.+))?$/);\n if (m) out[m[1]!] = m[2] || true;\n }\n return out;\n}\n\ninterface UpdateContext {\n cfg: ReturnType<typeof loadConfig>;\n channel: \"release\" | \"preview\" | string;\n checkOnly: boolean;\n force: boolean;\n bdsPath: string;\n backupDir: string;\n preserve: string[];\n autoRestart: boolean;\n qqNotify: boolean;\n}\n\nfunction buildContext(): UpdateContext {\n const cfg = loadConfig();\n const args = parseArgs(process.argv.slice(2));\n const { bds_path, backup_dir, preserve } = resolvePaths(cfg);\n const channel = String(args[\"channel\"] || cfg.channel || \"release\");\n return {\n cfg,\n channel,\n checkOnly: !!args[\"check-only\"],\n force: !!args[\"force\"],\n bdsPath: bds_path,\n backupDir: backup_dir,\n preserve,\n autoRestart: !args[\"no-start\"] && cfg.auto_restart !== false,\n qqNotify: !!cfg.qq_notify,\n };\n}\n\nasync function doBackup(\n bdsPath: string,\n backupDir: string,\n preserve: string[]\n): Promise<{ path: string; size: number }> {\n const dateStr = new Date().toISOString().slice(0, 10);\n const dest = path.join(backupDir, dateStr);\n fs.mkdirSync(dest, { recursive: true });\n\n let anyCopied = false;\n for (const item of preserve) {\n const src = path.join(bdsPath, item);\n const target = path.join(dest, item);\n if (!fs.existsSync(src)) continue;\n fs.mkdirSync(path.dirname(target), { recursive: true });\n if (fs.statSync(src).isDirectory()) copyDirSync(src, target);\n else copyFileSyncSafe(src, target);\n anyCopied = true;\n log.info(`\u5DF2\u5907\u4EFD: ${item}`);\n }\n\n // \u5373\u4F7F\u5168\u90E8 preserve \u90FD\u8DF3\u8FC7\uFF0C\u4E5F\u8BA9\u76EE\u5F55\u5B58\u5728\u4EE5\u4FBF\u8BB0\u5F55\u65F6\u95F4\u6233\n if (!anyCopied) {\n log.info(`\u6CA1\u6709\u9700\u8981\u5907\u4EFD\u7684\u6587\u4EF6 (preserve \u5217\u8868\u4E3A\u7A7A\u6216\u5168\u90E8\u7F3A\u5931)`);\n }\n return { path: dest, size: getDirSize(dest) };\n}\n\n/** \u5F02\u6B65\u6062\u590D preserves \u4ECE\u5907\u4EFD\u5230 BDS \u8DEF\u5F84 */\nasync function restorePreserves(bdsPath: string, backupDir: string, preserve: string[]): Promise<void> {\n for (const item of preserve) {\n const src = path.join(backupDir, item);\n const dest = path.join(bdsPath, item);\n if (!fs.existsSync(src)) continue;\n try {\n if (fs.statSync(src).isDirectory()) {\n if (fs.existsSync(dest)) emptyDirSync(dest);\n copyDirSync(src, dest);\n } else {\n fs.mkdirSync(path.dirname(dest), { recursive: true });\n copyFileSyncSafe(src, dest);\n }\n log.info(`\u5DF2\u6062\u590D: ${item}`);\n } catch (e) {\n log.warn(`\u6062\u590D\u5931\u8D25 ${item}: ${(e as Error).message}`);\n }\n }\n}\n\n/** \u7B49\u5F85\u64CD\u4F5C\u7CFB\u7EDF\u786E\u8BA4 BDS \u9000\u51FA\uFF0C\u907F\u514D\u4ECD\u5360\u7528\u53EF\u6267\u884C\u6587\u4EF6\u65F6\u8986\u76D6\u5B89\u88C5\u76EE\u5F55\u3002 */\nasync function waitForBdsStopped(timeoutMs = 10_000): Promise<void> {\n const deadline = Date.now() + timeoutMs;\n let status = await probeBdsStatus({ rootDir: ROOT_DIR });\n while (status.state !== \"stopped\" && Date.now() < deadline) {\n await new Promise<void>((resolve) => setTimeout(resolve, 250));\n status = await probeBdsStatus({ rootDir: ROOT_DIR });\n }\n if (status.state !== \"stopped\") {\n throw new Error(`BDS \u8FDB\u7A0B ${status.pid} \u4ECD\u5728\u8FD0\u884C\uFF0C\u5DF2\u53D6\u6D88\u6587\u4EF6\u8986\u76D6`);\n }\n}\n\n/** \u628A zip \u89E3\u538B\u5230 destDir (\u8986\u76D6) \u2014 \u7ECF zipx \u5B89\u5168\u89E3\u538B */\nasync function extractZipToBds(zipPath: string, destDir: string): Promise<void> {\n // \u62BD\u51FA\u5230\u4E34\u65F6\u76EE\u5F55\uFF0C\u907F\u514D\u65E7\u5185\u5BB9\u5E72\u6270\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"bds-extract-\"));\n try {\n await extractZipFileToDir(zipPath, tmpDir);\n // \u628A\u4E34\u65F6\u76EE\u5F55\u91CC\u7684\u5185\u5BB9\u590D\u5236\u5230 BDS \u8DEF\u5F84\n for (const entry of fs.readdirSync(tmpDir)) {\n const srcPath = path.join(tmpDir, entry);\n const destPath = path.join(destDir, entry);\n if (fs.statSync(srcPath).isDirectory()) {\n if (fs.existsSync(destPath)) emptyDirSync(destPath);\n copyDirSync(srcPath, destPath);\n } else {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n } finally {\n rmSafe(tmpDir);\n }\n}\n\nexport async function runUpdate(): Promise<number> {\n const startTime = Date.now();\n const ctx = buildContext();\n const { cfg, channel, checkOnly, force, bdsPath, backupDir, preserve, autoRestart, qqNotify } = ctx;\n\n log.info(`===== \u5F00\u59CB\u68C0\u67E5\u66F4\u65B0 (${channel}) =====`);\n fs.mkdirSync(bdsPath, { recursive: true });\n fs.mkdirSync(backupDir, { recursive: true });\n\n // 1. \u5F53\u524D\u7248\u672C\n const exePath = bdsExePath(bdsPath);\n const currentVer = await getCurrentVersionAsync(exePath).catch(() => getCurrentVersionSync(exePath));\n log.info(`\u5F53\u524D\u7248\u672C: ${currentVer}`);\n\n // 2. \u83B7\u53D6\u6700\u65B0\u7248\u672C\n let latestVer: string;\n try {\n const info = await getVersionInfo(cfg, channel);\n latestVer = info.version;\n log.info(`\u6700\u65B0\u7248\u672C: ${latestVer}`);\n const cmp = compareVersions(latestVer, currentVer);\n if (cmp <= 0 && !force) {\n log.info(\"\u5DF2\u662F\u6700\u65B0\u7248\u672C\uFF0C\u65E0\u9700\u66F4\u65B0\");\n if (qqNotify) {\n await sendText(`\u2705 BDS \u5DF2\u662F\u6700\u65B0\u7248\u672C\\n\\n\u5F53\u524D: ${currentVer}\\n\u6700\u65B0: ${latestVer}`);\n }\n emitUpdateKv(\"CURRENT\", currentVer, log);\n emitUpdateKv(\"LATEST\", latestVer, log);\n emitUpdateResult(\"uptodate\", log);\n return 0;\n }\n } catch (e) {\n log.error(`\u83B7\u53D6\u7248\u672C\u4FE1\u606F\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u65E0\u6CD5\u83B7\u53D6\u7248\u672C\u4FE1\u606F: ${(e as Error).message}`);\n return 1;\n }\n\n // \u517C\u5BB9\u6027\u68C0\u67E5\n if (!force && !isVersionCompatible(cfg, latestVer)) {\n log.warn(`${latestVer} \u4E0D\u5728\u517C\u5BB9\u7248\u672C\u767D\u540D\u5355\u4E2D\uFF0C\u8DF3\u8FC7\u5347\u7EA7`);\n if (qqNotify) {\n await sendText(`\u26A0\uFE0F BDS ${latestVer} \u4E0D\u5728\u517C\u5BB9\u6027\u767D\u540D\u5355\uFF0C\u5DF2\u8DF3\u8FC7\u5347\u7EA7\u3002\u8BF7\u4EBA\u5DE5\u786E\u8BA4\u3002`);\n }\n emitUpdateResult(\"skipped\", log);\n return 2;\n }\n\n // 3. \u53D6\u4E0B\u8F7D\u94FE\u63A5\n let downloadUrls: string[];\n let hash: { sha1: string; sha256: string };\n try {\n const details = await fetchVersionDetails(cfg, channel, latestVer);\n downloadUrls = buildDownloadUrls(cfg, channel, latestVer, details);\n hash = { sha1: details.sha1, sha256: details.sha256 };\n } catch (e) {\n log.error(`\u83B7\u53D6\u4E0B\u8F7D\u8BE6\u60C5\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u4E0B\u8F7D\u8BE6\u60C5\u83B7\u53D6\u5931\u8D25: ${(e as Error).message}`);\n return 1;\n }\n\n if (checkOnly) {\n emitUpdateKv(\"CURRENT\", currentVer, log);\n emitUpdateKv(\"LATEST\", latestVer, log);\n emitUpdateKv(\"CHANNEL\", channel, log);\n emitUpdateKv(\"URLS\", String(downloadUrls.length), log);\n emitUpdateResult(\"check-only\", log);\n return 0;\n }\n\n log.info(`\u53D1\u73B0\u65B0\u7248\u672C: ${currentVer} \u2192 ${latestVer}`);\n\n // 4. QQ \u9884\u544A\n if (qqNotify) {\n await sendText(\n `\uD835\uDC0C\uD835\uDC22\uD835\uDC27\uD835\uDC1E\uD835\uDC1C\uD835\uDC2B\uD835\uDC1A\uD835\uDC1F\uD835\uDC2D \uD835\uDC01\uD835\uDC03\uD835\uDC12 \u66F4\u65B0\u901A\u77E5\\n\\n` +\n `\u68C0\u6D4B\u5230\u65B0\u7248\u672C\uFF01\\n\\n` +\n `\u5F53\u524D: ${currentVer}\\n` +\n `\u6700\u65B0: ${latestVer}\\n` +\n `\u9891\u9053: ${channel === \"preview\" ? \"\u9884\u89C8\u7248\" : \"\u6B63\u5F0F\u7248\"}\\n\\n` +\n `\u670D\u52A1\u5668\u5373\u5C06\u5F00\u59CB\u66F4\u65B0~ \u8BF7\u8010\u5FC3\u7B49\u5F85^(*\uFFE3(oo)\uFFE3)^`\n );\n const cl = await fetchChangelog(channel, latestVer);\n if (cl) {\n const text = `\uD83D\uDCCB ${latestVer} \u66F4\u65B0\u5185\u5BB9\u6982\u8981\\n\\n${cl.text.slice(0, 1500)}\\n\\n\u5B8C\u6574\u65E5\u5FD7: ${cl.url}`;\n if (cl.imageBase64) await sendWithImage(text, cl.imageBase64);\n else await sendText(text);\n } else {\n await sendText(`\uD83D\uDCCB ${latestVer} \u66F4\u65B0\u65E5\u5FD7\u76EE\u5F55: ${changelogSectionUrl(channel)}`);\n }\n }\n\n // 5. \u5907\u4EFD\n let backupInfo: { path: string; size: number };\n try {\n backupInfo = await doBackup(bdsPath, backupDir, preserve);\n log.info(`\u5907\u4EFD\u5B8C\u6210: ${backupInfo.path} (${(backupInfo.size / 1024 / 1024).toFixed(1)} MB)`);\n if (qqNotify) {\n await sendText(`\u2705 \u5907\u4EFD\u5B8C\u6210\\n\\n\u5927\u5C0F: ${(backupInfo.size / 1024 / 1024).toFixed(1)} MB\\n\u4F4D\u7F6E: ${backupInfo.path}`);\n }\n } catch (e) {\n log.error(`\u5907\u4EFD\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u5907\u4EFD\u5931\u8D25: ${(e as Error).message}\\n\u64CD\u4F5C\u5DF2\u4E2D\u6B62`);\n return 1;\n }\n\n // 6. \u5199\u56DE\u6EDA\u6807\u8BB0 (\u8DE8\u8FDB\u7A0B\u53EF\u6062\u590D)\n writeRollbackMarker({\n timestamp: Date.now(),\n bds_path: bdsPath,\n backup_dir: backupInfo.path,\n preserve,\n previous_version: currentVer,\n });\n\n // 7. \u505C\u670D\n const bds = createBdsManager({ detached: true });\n try {\n log.info(\"\u505C\u6B62 BDS \u670D\u52A1...\");\n await bds.stop();\n await waitForBdsStopped();\n log.info(\"BDS \u5DF2\u505C\u6B62\");\n } catch (e) {\n log.error(`BDS \u505C\u6B62\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u505C\u670D\u5931\u8D25: ${(e as Error).message}\\n\u64CD\u4F5C\u5DF2\u4E2D\u6B62`);\n clearRollbackMarker();\n return 1;\n }\n\n // 8. \u4E0B\u8F7D (\u5168\u90E8\u5931\u8D25\u5219\u56DE\u6EDA)\n // \u7528 mkdtempSync \u521B\u5EFA\u4E34\u65F6 staging \u76EE\u5F55 - \u907F\u514D\u6C61\u67D3 SCRIPT_DIR\n const stagingDir = fs.mkdtempSync(path.join(os.tmpdir(), \"bds-update-\"));\n const zipPath = path.join(stagingDir, `bedrock-server-${latestVer}.zip`);\n let downloaded = false;\n try {\n log.info(`\u5F00\u59CB\u4E0B\u8F7D ${latestVer}...`);\n if (qqNotify) await sendText(`\uD83D\uDCE5 \u6B63\u5728\u4E0B\u8F7D BDS ${latestVer}...`);\n\n let lastErr: Error | null = null;\n const downloadTimeoutMs = (cfg.download_timeout ?? 120) * 1000;\n /* stderr \u88AB pipe \u65F6\u7531 logger \u8F93\u51FA\u5E26\u6761\u5F62\u56FE\u7684\u8FDB\u5EA6\u884C\uFF0C\u4F9B sfmc REPL \u5C55\u793A\u3002 */\n if (isTaskbarSupported() && process.stdout.isTTY) {\n log.info(\"\u68C0\u6D4B\u5230 Windows Terminal,\u4EFB\u52A1\u680F\u8FDB\u5EA6\u5DF2\u542F\u7528 (OSC 9;4)\");\n }\n for (const url of downloadUrls) {\n /* \u6BCF\u6B21\u5C1D\u8BD5\u65B0\u5EFA bar + binder\uFF0C\u907F\u514D\u5931\u8D25\u91CD\u8BD5\u65F6 started \u72B6\u6001\u6B8B\u7559\uFF08LSP\uFF09 */\n const progressBar = createTerminalProgress({\n stream: process.stderr,\n logger: (msg) => log.info(msg),\n format: \"\u4E0B\u8F7D\u8FDB\u5EA6 | {bar} | {percentage}% | {value}/{total} MB | \u901F\u5EA6: {speed}\",\n });\n const onByteProgress = bindByteProgressToBar(progressBar, {\n speedSampleMs: 0,\n onProgress: (dl, total) => {\n const pct = total > 0 ? (dl / total) * 100 : 0;\n setTaskbarProgress(pct);\n },\n });\n try {\n setTaskbarProgress(0);\n await httpDownload(url, zipPath, {\n totalTimeoutMs: Math.max(downloadTimeoutMs, 600_000), // \u4E0D\u5C11\u4E8E 10 \u5206\u949F\n onProgress: onByteProgress,\n });\n if (progressBar.active) progressBar.stop();\n // \u4E0B\u8F7D\u5B8C\u6210,\u4EFB\u52A1\u680F\u6536\u5230 100% \u7EFF\u6761\u540E\u6E05\u6389\n setTaskbarProgress(100);\n clearTaskbarProgress();\n downloaded = true;\n lastErr = null;\n break;\n } catch (e) {\n if (progressBar.active) progressBar.stop();\n // \u4E0B\u8F7D\u5931\u8D25,\u4EFB\u52A1\u680F\u4EAE\u7EA2\n setTaskbarProgress(100, \"error\");\n clearTaskbarProgress();\n lastErr = e as Error;\n log.warn(`${url} \u4E0D\u53EF\u7528: ${lastErr.message}\uFF0C\u5C1D\u8BD5\u5907\u7528\u5730\u5740...`);\n }\n }\n if (!downloaded && lastErr) throw lastErr;\n\n const zipSizeMB = (fs.statSync(zipPath).size / 1024 / 1024).toFixed(1);\n log.info(`\u4E0B\u8F7D\u5B8C\u6210 (${zipSizeMB} MB)`);\n\n // \u6D41\u5F0F\u54C8\u5E0C\u6821\u9A8C\n if (hash.sha1 || hash.sha256) {\n const algo = hash.sha256 ? \"SHA256\" : \"SHA1\";\n log.info(`\u6821\u9A8C\u6587\u4EF6\u5B8C\u6574\u6027 (${algo})...`);\n const ok = await verifyFileHash(zipPath, hash.sha1, hash.sha256);\n if (!ok) throw new Error(`${algo} \u6821\u9A8C\u4E0D\u901A\u8FC7\uFF0C\u6587\u4EF6\u53EF\u80FD\u635F\u574F`);\n log.info(`${algo} \u6821\u9A8C\u901A\u8FC7`);\n }\n } catch (e) {\n log.error(`\u4E0B\u8F7D\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u4E0B\u8F7D\u5931\u8D25: ${(e as Error).message}\\nBDS \u5DF2\u505C\u6B62\uFF0C\u8BF7\u624B\u52A8\u6062\u590D`);\n // \u81EA\u52A8\u56DE\u6EDA\n rollbackFromBackup({\n timestamp: Date.now(),\n bds_path: bdsPath,\n backup_dir: backupInfo.path,\n preserve,\n previous_version: currentVer,\n });\n rmSafe(stagingDir);\n return 1;\n }\n\n // 9. \u89E3\u538B + \u90E8\u7F72\n try {\n await waitForBdsStopped();\n } catch (e) {\n log.error(`\u90E8\u7F72\u5DF2\u4E2D\u6B62: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n${(e as Error).message}\\n\u5C1A\u672A\u8986\u76D6\u5B89\u88C5\u76EE\u5F55`);\n rmSafe(stagingDir);\n clearRollbackMarker();\n return 1;\n }\n try {\n log.info(\"\u89E3\u538B\u4E2D...\");\n // \u5148\u6E05\u7A7A BDS \u76EE\u5F55\n emptyDirSync(bdsPath);\n await extractZipToBds(zipPath, bdsPath);\n ensureBdsExecutable(exePath);\n log.info(\"\u89E3\u538B\u5B8C\u6210\");\n } catch (e) {\n log.error(`\u89E3\u538B\u5931\u8D25: ${(e as Error).message}`);\n const status = await probeBdsStatus({ rootDir: ROOT_DIR });\n if (status.state !== \"stopped\") {\n // \u5916\u90E8\u5B88\u62A4\u8FDB\u7A0B\u53EF\u80FD\u5728\u90E8\u7F72\u671F\u95F4\u518D\u6B21\u62C9\u8D77 BDS\uFF1B\u4E0D\u80FD\u5BF9\u8FD0\u884C\u4E2D\u7684\u76EE\u5F55\u7EE7\u7EED\u6E05\u7406\u3002\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u89E3\u538B\u5931\u8D25: ${(e as Error).message}\\nBDS \u4ECD\u5728\u8FD0\u884C\uFF0C\u8BF7\u5148\u505C\u670D\u5E76\u624B\u52A8\u6062\u590D`);\n rmSafe(stagingDir);\n return 1;\n }\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u89E3\u538B\u5931\u8D25: ${(e as Error).message}\\nBDS \u5DF2\u505C\u6B62\uFF0C\u8BF7\u624B\u52A8\u6062\u590D`);\n // \u56DE\u6EDA: \u6E05\u7A7A + \u4ECE\u5907\u4EFD\u6062\u590D preserves\n emptyDirSync(bdsPath);\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n rmSafe(stagingDir);\n return 1;\n } finally {\n rmSafe(zipPath); // \u6E05\u6389 staging zip\n }\n\n // 10. \u5B8C\u6574\u6027\u68C0\u67E5 (\u907F\u514D\u89E3\u538B\u51FA\u7A7A/\u7F3A\u6587\u4EF6\u7684\u75C5\u6001\u5305)\n const verify = verifyBdsInstall(bdsPath, bdsInstallRequiredFiles());\n if (!verify.ok) {\n log.error(`\u89E3\u538B\u540E\u7684 BDS \u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5931\u6587\u4EF6: ${verify.missing.join(\", \")}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u90E8\u7F72\u540E\u7F3A\u5931\u5173\u952E\u6587\u4EF6: ${verify.missing.join(\", \")}`);\n emptyDirSync(bdsPath);\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n rmSafe(stagingDir);\n return 1;\n }\n\n // 11. \u6062\u590D preserves (zip \u89E3\u538B\u65F6\u8FD9\u4E9B\u76EE\u5F55\u53EF\u80FD\u88AB\u8986\u76D6)\n await restorePreserves(bdsPath, backupInfo.path, preserve);\n\n // 11b. \u5B89\u88C5\u6536\u5C3E\uFF1A\u8865\u9F50\u5FC5\u8981\u914D\u7F6E\uFF0C\u5E76\u5C06 server.properties \u6CE8\u91CA\u672C\u5730\u5316\n ensureEmitServerTelemetry(bdsPath, log);\n ensureNetherNetTransport(bdsPath, log);\n localizeServerProperties(bdsPath, { logger: log, rootDir: ROOT_DIR });\n\n // 12. \u5199\u5165\u7248\u672C\u7F13\u5B58\n const newExeHash = await hashFileAsync(exePath, \"sha256\").catch(() => \"\");\n if (newExeHash) {\n saveVersionCache(latestVer, newExeHash);\n log.info(`\u5DF2\u8BB0\u5F55\u7248\u672C ${latestVer} \u7684 SHA256`);\n }\n\n // 13. \u542F\u52A8 BDS\n if (autoRestart) {\n try {\n log.info(\"\u542F\u52A8 BDS...\");\n await bds.start();\n } catch (e) {\n log.error(`\u542F\u52A8\u5931\u8D25: ${(e as Error).message}`);\n await sendText(`\u274C BDS \u66F4\u65B0\u5931\u8D25\\n\\n\u542F\u52A8\u5931\u8D25: ${(e as Error).message}\\n\u8BF7\u624B\u52A8\u542F\u52A8 BDS`);\n // \u6CE8\u610F: \u6B64\u65F6 BDS \u5DF2\u7ECF\u90E8\u7F72\u5B8C\u6210\uFF0C\u542F\u52A8\u5931\u8D25 \u2192 \u542F\u52A8\u95EE\u9898\uFF0C\u4E0D\u505A\u6587\u4EF6\u7EA7\u56DE\u6EDA\n rmSafe(stagingDir);\n clearRollbackMarker();\n return 1;\n }\n }\n\n rmSafe(stagingDir);\n clearRollbackMarker();\n\n // 14. QQ \u901A\u77E5\u7ED3\u679C\n const durationMs = Date.now() - startTime;\n if (qqNotify) {\n await sendText(\n `\u2705 BDS \u66F4\u65B0\u5B8C\u6210\\n\\n` +\n `${currentVer} \u2192 ${latestVer}\\n` +\n `\u8017\u65F6: ${(durationMs / 1000).toFixed(1)}s\\n` +\n `${autoRestart ? \"\u670D\u52A1\u5668\u5DF2\u91CD\u65B0\u542F\u52A8\" : \"\u8BF7\u624B\u52A8\u91CD\u542F\u670D\u52A1\u5668\"}`\n );\n }\n log.info(`===== \u66F4\u65B0\u5B8C\u6210 (${(durationMs / 1000).toFixed(1)}s) =====`);\n /* \u673A\u5668\u53EF\u8BFB\u7ED3\u679C\u6807\u8BB0\uFF1A\u4F9B sfmc \u7B49\u76D1\u7763\u5668\u5224\u65AD\u300C\u771F\u6B63\u5B8C\u6210\u90E8\u7F72\u300D\uFF0C\u52FF\u4F9D\u8D56\u672C\u5730\u5316\u65E5\u5FD7\u6587\u6848\u3002 */\n emitUpdateResult(\"deployed\", log);\n return 0;\n}\n\nfunction isMain(): boolean {\n // sfmc supervisor \u901A\u8FC7 SFMC_SERVICE \u62C9\u8D77\u5B50\u8FDB\u7A0B\u65F6\u4F18\u5148\u5224\u5B9A\n if (process.env.SFMC_SERVICE === \"update\") return true;\n return isMainModule(import.meta.url);\n}\n\nif (isMain()) {\n runUpdate()\n .then((code) => {\n closeLog();\n process.exit(code);\n })\n .catch((e) => {\n log.error(`\u672A\u6355\u83B7\u9519\u8BEF: ${(e as Error).message}`);\n closeLog();\n process.exit(1);\n });\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import fs from "node:fs";
2
3
  import path from "node:path";
3
4
  import process from "node:process";
4
5
  import { readLevelName } from "./pack-manager.js";
@@ -51,6 +52,14 @@ async function main() {
51
52
  const out = need(args, "out");
52
53
  const name = need(args, "name");
53
54
  const icon = args["icon"];
55
+ let dependencies;
56
+ if (args["dependencies-json"]) {
57
+ try {
58
+ const raw = fs.readFileSync(path.resolve(args["dependencies-json"]), "utf8");
59
+ dependencies = JSON.parse(raw);
60
+ } catch {
61
+ }
62
+ }
54
63
  await mod.assembleBehaviorPack({
55
64
  srcDir: path.resolve(src),
56
65
  outDir: path.resolve(out),
@@ -59,7 +68,8 @@ async function main() {
59
68
  description: args["description"],
60
69
  ...icon ? { iconSrc: path.resolve(icon) } : {},
61
70
  ...args["uuid"] ? { uuid: args["uuid"] } : {},
62
- ...args["module-uuid"] ? { moduleUuid: args["module-uuid"] } : {}
71
+ ...args["module-uuid"] ? { moduleUuid: args["module-uuid"] } : {},
72
+ ...dependencies ? { dependencies } : {}
63
73
  });
64
74
  process.stdout.write(`[pack-manager] assembled BP at ${out}
65
75
  `);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/cli-pack-manager.ts"],
4
- "sourcesContent": ["#!/usr/bin/env node\n/**\n * pack-manager CLI \u2014 thin wrapper around the pack-manager pure functions\n * so spawnService can call it as a sub-process.\n *\n * node bds-tools/dist/pack-manager.js assemble-bp --src <dir> --out <dir> --name <name> [--uuid <uuid>] [--module-uuid <uuid>] [--version 1,0,0] [--description \"...\"] [--icon <png>]\n * node bds-tools/dist/pack-manager.js assemble-rp (--modules-dir <dir>|--modules-json <file>) --out <dir> --name <name> [--uuid <uuid>] [--module-uuid <uuid>] [--version 1,0,0] [--description \"...\"]\n * node bds-tools/dist/pack-manager.js deploy --bds-root <dir> --level <name> --bp-src <dir> [--rp-src <dir>] --bp-name <name> [--rp-name <name>] [--clear-rp]\n * node bds-tools/dist/pack-manager.js enable-pack --worlds-dir <dir> --level <name> --kind behavior|resource --pack-id <uuid> --version 1,0,0\n * node bds-tools/dist/pack-manager.js disable-pack --worlds-dir <dir> --level <name> --kind behavior|resource --pack-id <uuid>\n * node bds-tools/dist/pack-manager.js ensure-permission --bds-root <dir> --pack-id <uuid>\n * node bds-tools/dist/pack-manager.js read-level --bds-root <dir>\n * node bds-tools/dist/pack-manager.js read-manifest --pack-dir <dir>\n * node bds-tools/dist/pack-manager.js has-pack --worlds-dir <dir> --level <name> --kind behavior|resource --pack-id <uuid>\n * node bds-tools/dist/pack-manager.js list-packs --worlds-dir <dir> --level <name> --kind behavior|resource\n *\n * The pure-function API lives in pack-manager.ts. This CLI exists so a\n * spawnService child process doesn't have to deal with module resolution \u2014\n * it just gets SFMC_ROOT injected, finds its own dist sibling,\n * and reads JSON flags from argv.\n */\n\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { readLevelName } from \"./pack-manager.js\";\n\nfunction die(msg: string, code = 1): never {\n process.stderr.write(`[pack-manager] ${msg}\\n`);\n process.exit(code);\n}\n\nfunction parseArgs(argv: string[]): { [k: string]: string | undefined } {\n const out: { [k: string]: string | undefined } = {};\n for (let i = 0; i < argv.length; i++) {\n const a = argv[i];\n if (a && a.startsWith(\"--\")) {\n const key = a.slice(2);\n const next = argv[++i];\n /* \u5E03\u5C14\u65D7\u6807(\u65E0\u503C\u6216\u4E0B\u4E00\u53C2\u4E5F\u662F --xxx) */\n if (next === undefined || next.startsWith(\"--\")) {\n out[key] = \"1\";\n if (next !== undefined) i--;\n } else {\n out[key] = next;\n }\n }\n }\n return out;\n}\n\nfunction need(args: { [k: string]: string | undefined }, key: string): string {\n const v = args[key];\n if (!v) die(`--${key} required`);\n return v;\n}\n\nfunction parseVersion(s: string | undefined): [number, number, number] {\n if (!s) return [1, 0, 0];\n const parts = s.split(\",\").map((x) => Number(x.trim()));\n if (parts.length !== 3 || parts.some((n) => !Number.isInteger(n) || (n as number) < 0)) {\n die(`invalid --version (expected \"M,m,p\"): ${s}`);\n }\n return parts as [number, number, number];\n}\n\nasync function main(): Promise<void> {\n const argv = process.argv.slice(2);\n if (argv.length === 0) {\n die(\"usage: pack-manager <verb> [--flags]\");\n }\n const verb = argv[0];\n const args = parseArgs(argv.slice(1));\n\n const mod = await import(\"./pack-manager.js\");\n\n switch (verb) {\n case \"assemble-bp\": {\n const src = need(args, \"src\");\n const out = need(args, \"out\");\n const name = need(args, \"name\");\n const icon = args[\"icon\"];\n await mod.assembleBehaviorPack({\n srcDir: path.resolve(src),\n outDir: path.resolve(out),\n projectName: name,\n version: parseVersion(args[\"version\"]),\n description: args[\"description\"],\n ...(icon ? { iconSrc: path.resolve(icon) } : {}),\n ...(args[\"uuid\"] ? { uuid: args[\"uuid\"] } : {}),\n ...(args[\"module-uuid\"] ? { moduleUuid: args[\"module-uuid\"] } : {}),\n });\n process.stdout.write(`[pack-manager] assembled BP at ${out}\\n`);\n return;\n }\n case \"assemble-rp\": {\n const out = need(args, \"out\");\n const name = need(args, \"name\");\n /* OCP:\u663E\u5F0F map \u4F18\u5148;\u5426\u5219\u56DE\u9000\u626B\u63CF --modules-dir */\n let map: Record<string, string>;\n if (args[\"modules-json\"]) {\n map = mod.loadModuleResourcePackMap(path.resolve(args[\"modules-json\"]));\n } else {\n const modulesDir = need(args, \"modules-dir\");\n map = mod.scanModuleResourcePacks(path.resolve(modulesDir));\n }\n await mod.assembleResourcePack({\n moduleResourceDirs: map,\n outDir: path.resolve(out),\n projectName: name,\n version: parseVersion(args[\"version\"]),\n description: args[\"description\"],\n ...(args[\"uuid\"] ? { uuid: args[\"uuid\"] } : {}),\n ...(args[\"module-uuid\"] ? { moduleUuid: args[\"module-uuid\"] } : {}),\n });\n process.stdout.write(`[pack-manager] assembled RP at ${out} (${Object.keys(map).length} modules)\\n`);\n return;\n }\n case \"deploy\": {\n const bdsRoot = need(args, \"bds-root\");\n const level = need(args, \"level\");\n const bpSrc = need(args, \"bp-src\");\n const bpName = need(args, \"bp-name\");\n const rpSrc = args[\"rp-src\"];\n const rpName = args[\"rp-name\"];\n const clearRp = args[\"clear-rp\"] === \"1\" || args[\"clear-rp\"] === \"true\";\n await mod.deployToBDS({\n bdsRoot: path.resolve(bdsRoot),\n levelName: level,\n behaviorPackSrc: path.resolve(bpSrc),\n ...(rpSrc ? { resourcePackSrc: path.resolve(rpSrc) } : {}),\n bpName,\n ...(rpName ? { rpName } : {}),\n ...(clearRp ? { clearResourcePack: true } : {}),\n });\n process.stdout.write(`[pack-manager] deployed to ${mod.bdsWorldLevelDir(path.resolve(bdsRoot), level)}\\n`);\n return;\n }\n case \"enable-pack\": {\n const worldsDir = need(args, \"worlds-dir\");\n const level = need(args, \"level\");\n const kind = need(args, \"kind\") as \"behavior\" | \"resource\";\n const packId = need(args, \"pack-id\");\n await mod.enablePackInWorld({\n worldsDir: path.resolve(worldsDir),\n levelName: level,\n kind,\n packUuid: packId,\n version: parseVersion(args[\"version\"]),\n });\n process.stdout.write(`[pack-manager] enabled ${kind} pack ${packId} in ${level}\\n`);\n return;\n }\n case \"disable-pack\": {\n const worldsDir = need(args, \"worlds-dir\");\n const level = need(args, \"level\");\n const kind = need(args, \"kind\") as \"behavior\" | \"resource\";\n const packId = need(args, \"pack-id\");\n await mod.disablePackInWorld({\n worldsDir: path.resolve(worldsDir),\n levelName: level,\n kind,\n packUuid: packId,\n version: parseVersion(args[\"version\"] ?? \"1,0,0\"),\n });\n process.stdout.write(`[pack-manager] disabled ${kind} pack ${packId} in ${level}\\n`);\n return;\n }\n case \"ensure-permission\": {\n const bdsRoot = need(args, \"bds-root\");\n const packId = need(args, \"pack-id\");\n const root = path.resolve(bdsRoot);\n const wrote = await mod.ensureConfigPermission(root, packId);\n const rel = path.relative(root, mod.configPermissionPath(root, packId));\n process.stdout.write(\n wrote ? `[pack-manager] wrote ${rel}\\n` : `[pack-manager] ${rel} already exists \u2014 skipped\\n`\n );\n return;\n }\n case \"read-level\": {\n const root = need(args, \"bds-root\");\n const name = await readLevelName(path.resolve(root));\n process.stdout.write(`${name}\\n`);\n return;\n }\n case \"read-manifest\": {\n const packDir = need(args, \"pack-dir\");\n const header = mod.readPackManifestHeader(path.resolve(packDir));\n if (!header) {\n process.stdout.write(\"null\\n\");\n return;\n }\n process.stdout.write(`${JSON.stringify(header)}\\n`);\n return;\n }\n case \"has-pack\": {\n const worldsDir = need(args, \"worlds-dir\");\n const level = need(args, \"level\");\n const kind = need(args, \"kind\") as \"behavior\" | \"resource\";\n const packId = need(args, \"pack-id\");\n const ok = mod.worldPackListHas(path.resolve(worldsDir), level, kind, packId);\n process.stdout.write(ok ? \"1\\n\" : \"0\\n\");\n return;\n }\n case \"list-packs\": {\n /* \u6743\u5A01\u4E16\u754C\u6E05\u5355\u8BFB\u53D6 \u2014 \u8C03\u7528\u65B9\u52FF\u518D\u76F4\u63A5\u89E3\u6790 world_*_packs.json(Demeter/DRY) */\n const worldsDir = need(args, \"worlds-dir\");\n const level = need(args, \"level\");\n const kind = need(args, \"kind\") as \"behavior\" | \"resource\";\n const list = mod.readWorldPackList(path.resolve(worldsDir), level, kind);\n process.stdout.write(`${JSON.stringify(list)}\\n`);\n return;\n }\n case \"list-installed\":\n case \"bump-version\":\n case \"install-dir\":\n case \"discover-packs\": {\n /* OCP: world-packs \u52A8\u8BCD\u8868\u6269\u5C55\uFF0C\u907F\u514D\u6BCF case \u91CD\u590D dynamic import\uFF08DRY\uFF09 */\n const wp = await import(\"./world-packs.js\");\n if (verb === \"list-installed\") {\n const bdsRoot = need(args, \"bds-root\");\n const level = need(args, \"level\");\n const list = wp.listInstalledWorldPacks(path.resolve(bdsRoot), level);\n process.stdout.write(`${JSON.stringify(list)}\\n`);\n return;\n }\n if (verb === \"bump-version\") {\n const packDir = need(args, \"pack-dir\");\n const next = wp.bumpPackPatchVersion(path.resolve(packDir));\n process.stdout.write(`${JSON.stringify({ version: next })}\\n`);\n return;\n }\n if (verb === \"install-dir\") {\n const src = need(args, \"src\");\n const destParent = need(args, \"dest-parent\");\n const force = !!args[\"force\"];\n const r = await wp.installPackDirectory({\n srcDir: path.resolve(src),\n destParent: path.resolve(destParent),\n force,\n ...(args[\"folder-name\"] ? { folderName: args[\"folder-name\"] } : {}),\n });\n process.stdout.write(`${JSON.stringify(r)}\\n`);\n if (!r.ok && !r.conflict) process.exit(1);\n return;\n }\n {\n const root = need(args, \"root\");\n const depth = args[\"max-depth\"] ? Number(args[\"max-depth\"]) : 4;\n const resolved = await wp.resolvePackRoots(path.resolve(root), { maxDirDepth: depth });\n try {\n process.stdout.write(`${JSON.stringify(resolved.roots)}\\n`);\n } finally {\n resolved.dispose();\n }\n return;\n }\n }\n default:\n die(`unknown verb: ${verb}`);\n }\n}\n\nmain().catch((err: unknown) => {\n const msg = err instanceof Error ? (err.stack ?? err.message) : String(err);\n die(msg);\n});\n"],
5
- "mappings": ";AAsBA,OAAO,UAAU;AACjB,OAAO,aAAa;AACpB,SAAS,qBAAqB;AAE9B,SAAS,IAAI,KAAa,OAAO,GAAU;AACzC,UAAQ,OAAO,MAAM,kBAAkB,GAAG;AAAA,CAAI;AAC9C,UAAQ,KAAK,IAAI;AACnB;AAEA,SAAS,UAAU,MAAqD;AACtE,QAAM,MAA2C,CAAC;AAClD,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,IAAI,KAAK,CAAC;AAChB,QAAI,KAAK,EAAE,WAAW,IAAI,GAAG;AAC3B,YAAM,MAAM,EAAE,MAAM,CAAC;AACrB,YAAM,OAAO,KAAK,EAAE,CAAC;AAErB,UAAI,SAAS,UAAa,KAAK,WAAW,IAAI,GAAG;AAC/C,YAAI,GAAG,IAAI;AACX,YAAI,SAAS,OAAW;AAAA,MAC1B,OAAO;AACL,YAAI,GAAG,IAAI;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,KAAK,MAA2C,KAAqB;AAC5E,QAAM,IAAI,KAAK,GAAG;AAClB,MAAI,CAAC,EAAG,KAAI,KAAK,GAAG,WAAW;AAC/B,SAAO;AACT;AAEA,SAAS,aAAa,GAAiD;AACrE,MAAI,CAAC,EAAG,QAAO,CAAC,GAAG,GAAG,CAAC;AACvB,QAAM,QAAQ,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,OAAO,EAAE,KAAK,CAAC,CAAC;AACtD,MAAI,MAAM,WAAW,KAAK,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,UAAU,CAAC,KAAM,IAAe,CAAC,GAAG;AACtF,QAAI,yCAAyC,CAAC,EAAE;AAAA,EAClD;AACA,SAAO;AACT;AAEA,eAAe,OAAsB;AACnC,QAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,MAAI,KAAK,WAAW,GAAG;AACrB,QAAI,sCAAsC;AAAA,EAC5C;AACA,QAAM,OAAO,KAAK,CAAC;AACnB,QAAM,OAAO,UAAU,KAAK,MAAM,CAAC,CAAC;AAEpC,QAAM,MAAM,MAAM,OAAO,mBAAmB;AAE5C,UAAQ,MAAM;AAAA,IACZ,KAAK,eAAe;AAClB,YAAM,MAAM,KAAK,MAAM,KAAK;AAC5B,YAAM,MAAM,KAAK,MAAM,KAAK;AAC5B,YAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,YAAM,OAAO,KAAK,MAAM;AACxB,YAAM,IAAI,qBAAqB;AAAA,QAC7B,QAAQ,KAAK,QAAQ,GAAG;AAAA,QACxB,QAAQ,KAAK,QAAQ,GAAG;AAAA,QACxB,aAAa;AAAA,QACb,SAAS,aAAa,KAAK,SAAS,CAAC;AAAA,QACrC,aAAa,KAAK,aAAa;AAAA,QAC/B,GAAI,OAAO,EAAE,SAAS,KAAK,QAAQ,IAAI,EAAE,IAAI,CAAC;AAAA,QAC9C,GAAI,KAAK,MAAM,IAAI,EAAE,MAAM,KAAK,MAAM,EAAE,IAAI,CAAC;AAAA,QAC7C,GAAI,KAAK,aAAa,IAAI,EAAE,YAAY,KAAK,aAAa,EAAE,IAAI,CAAC;AAAA,MACnE,CAAC;AACD,cAAQ,OAAO,MAAM,kCAAkC,GAAG;AAAA,CAAI;AAC9D;AAAA,IACF;AAAA,IACA,KAAK,eAAe;AAClB,YAAM,MAAM,KAAK,MAAM,KAAK;AAC5B,YAAM,OAAO,KAAK,MAAM,MAAM;AAE9B,UAAI;AACJ,UAAI,KAAK,cAAc,GAAG;AACxB,cAAM,IAAI,0BAA0B,KAAK,QAAQ,KAAK,cAAc,CAAC,CAAC;AAAA,MACxE,OAAO;AACL,cAAM,aAAa,KAAK,MAAM,aAAa;AAC3C,cAAM,IAAI,wBAAwB,KAAK,QAAQ,UAAU,CAAC;AAAA,MAC5D;AACA,YAAM,IAAI,qBAAqB;AAAA,QAC7B,oBAAoB;AAAA,QACpB,QAAQ,KAAK,QAAQ,GAAG;AAAA,QACxB,aAAa;AAAA,QACb,SAAS,aAAa,KAAK,SAAS,CAAC;AAAA,QACrC,aAAa,KAAK,aAAa;AAAA,QAC/B,GAAI,KAAK,MAAM,IAAI,EAAE,MAAM,KAAK,MAAM,EAAE,IAAI,CAAC;AAAA,QAC7C,GAAI,KAAK,aAAa,IAAI,EAAE,YAAY,KAAK,aAAa,EAAE,IAAI,CAAC;AAAA,MACnE,CAAC;AACD,cAAQ,OAAO,MAAM,kCAAkC,GAAG,KAAK,OAAO,KAAK,GAAG,EAAE,MAAM;AAAA,CAAa;AACnG;AAAA,IACF;AAAA,IACA,KAAK,UAAU;AACb,YAAM,UAAU,KAAK,MAAM,UAAU;AACrC,YAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,YAAM,QAAQ,KAAK,MAAM,QAAQ;AACjC,YAAM,SAAS,KAAK,MAAM,SAAS;AACnC,YAAM,QAAQ,KAAK,QAAQ;AAC3B,YAAM,SAAS,KAAK,SAAS;AAC7B,YAAM,UAAU,KAAK,UAAU,MAAM,OAAO,KAAK,UAAU,MAAM;AACjE,YAAM,IAAI,YAAY;AAAA,QACpB,SAAS,KAAK,QAAQ,OAAO;AAAA,QAC7B,WAAW;AAAA,QACX,iBAAiB,KAAK,QAAQ,KAAK;AAAA,QACnC,GAAI,QAAQ,EAAE,iBAAiB,KAAK,QAAQ,KAAK,EAAE,IAAI,CAAC;AAAA,QACxD;AAAA,QACA,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,QAC3B,GAAI,UAAU,EAAE,mBAAmB,KAAK,IAAI,CAAC;AAAA,MAC/C,CAAC;AACD,cAAQ,OAAO,MAAM,8BAA8B,IAAI,iBAAiB,KAAK,QAAQ,OAAO,GAAG,KAAK,CAAC;AAAA,CAAI;AACzG;AAAA,IACF;AAAA,IACA,KAAK,eAAe;AAClB,YAAM,YAAY,KAAK,MAAM,YAAY;AACzC,YAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,YAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,YAAM,SAAS,KAAK,MAAM,SAAS;AACnC,YAAM,IAAI,kBAAkB;AAAA,QAC1B,WAAW,KAAK,QAAQ,SAAS;AAAA,QACjC,WAAW;AAAA,QACX;AAAA,QACA,UAAU;AAAA,QACV,SAAS,aAAa,KAAK,SAAS,CAAC;AAAA,MACvC,CAAC;AACD,cAAQ,OAAO,MAAM,0BAA0B,IAAI,SAAS,MAAM,OAAO,KAAK;AAAA,CAAI;AAClF;AAAA,IACF;AAAA,IACA,KAAK,gBAAgB;AACnB,YAAM,YAAY,KAAK,MAAM,YAAY;AACzC,YAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,YAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,YAAM,SAAS,KAAK,MAAM,SAAS;AACnC,YAAM,IAAI,mBAAmB;AAAA,QAC3B,WAAW,KAAK,QAAQ,SAAS;AAAA,QACjC,WAAW;AAAA,QACX;AAAA,QACA,UAAU;AAAA,QACV,SAAS,aAAa,KAAK,SAAS,KAAK,OAAO;AAAA,MAClD,CAAC;AACD,cAAQ,OAAO,MAAM,2BAA2B,IAAI,SAAS,MAAM,OAAO,KAAK;AAAA,CAAI;AACnF;AAAA,IACF;AAAA,IACA,KAAK,qBAAqB;AACxB,YAAM,UAAU,KAAK,MAAM,UAAU;AACrC,YAAM,SAAS,KAAK,MAAM,SAAS;AACnC,YAAM,OAAO,KAAK,QAAQ,OAAO;AACjC,YAAM,QAAQ,MAAM,IAAI,uBAAuB,MAAM,MAAM;AAC3D,YAAM,MAAM,KAAK,SAAS,MAAM,IAAI,qBAAqB,MAAM,MAAM,CAAC;AACtE,cAAQ,OAAO;AAAA,QACb,QAAQ,wBAAwB,GAAG;AAAA,IAAO,kBAAkB,GAAG;AAAA;AAAA,MACjE;AACA;AAAA,IACF;AAAA,IACA,KAAK,cAAc;AACjB,YAAM,OAAO,KAAK,MAAM,UAAU;AAClC,YAAM,OAAO,MAAM,cAAc,KAAK,QAAQ,IAAI,CAAC;AACnD,cAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AAChC;AAAA,IACF;AAAA,IACA,KAAK,iBAAiB;AACpB,YAAM,UAAU,KAAK,MAAM,UAAU;AACrC,YAAM,SAAS,IAAI,uBAAuB,KAAK,QAAQ,OAAO,CAAC;AAC/D,UAAI,CAAC,QAAQ;AACX,gBAAQ,OAAO,MAAM,QAAQ;AAC7B;AAAA,MACF;AACA,cAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,MAAM,CAAC;AAAA,CAAI;AAClD;AAAA,IACF;AAAA,IACA,KAAK,YAAY;AACf,YAAM,YAAY,KAAK,MAAM,YAAY;AACzC,YAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,YAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,YAAM,SAAS,KAAK,MAAM,SAAS;AACnC,YAAM,KAAK,IAAI,iBAAiB,KAAK,QAAQ,SAAS,GAAG,OAAO,MAAM,MAAM;AAC5E,cAAQ,OAAO,MAAM,KAAK,QAAQ,KAAK;AACvC;AAAA,IACF;AAAA,IACA,KAAK,cAAc;AAEjB,YAAM,YAAY,KAAK,MAAM,YAAY;AACzC,YAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,YAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,YAAM,OAAO,IAAI,kBAAkB,KAAK,QAAQ,SAAS,GAAG,OAAO,IAAI;AACvE,cAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,IAAI,CAAC;AAAA,CAAI;AAChD;AAAA,IACF;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,kBAAkB;AAErB,YAAM,KAAK,MAAM,OAAO,kBAAkB;AAC1C,UAAI,SAAS,kBAAkB;AAC7B,cAAM,UAAU,KAAK,MAAM,UAAU;AACrC,cAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,cAAM,OAAO,GAAG,wBAAwB,KAAK,QAAQ,OAAO,GAAG,KAAK;AACpE,gBAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,IAAI,CAAC;AAAA,CAAI;AAChD;AAAA,MACF;AACA,UAAI,SAAS,gBAAgB;AAC3B,cAAM,UAAU,KAAK,MAAM,UAAU;AACrC,cAAM,OAAO,GAAG,qBAAqB,KAAK,QAAQ,OAAO,CAAC;AAC1D,gBAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,CAAI;AAC7D;AAAA,MACF;AACA,UAAI,SAAS,eAAe;AAC1B,cAAM,MAAM,KAAK,MAAM,KAAK;AAC5B,cAAM,aAAa,KAAK,MAAM,aAAa;AAC3C,cAAM,QAAQ,CAAC,CAAC,KAAK,OAAO;AAC5B,cAAM,IAAI,MAAM,GAAG,qBAAqB;AAAA,UACtC,QAAQ,KAAK,QAAQ,GAAG;AAAA,UACxB,YAAY,KAAK,QAAQ,UAAU;AAAA,UACnC;AAAA,UACA,GAAI,KAAK,aAAa,IAAI,EAAE,YAAY,KAAK,aAAa,EAAE,IAAI,CAAC;AAAA,QACnE,CAAC;AACD,gBAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,CAAC,CAAC;AAAA,CAAI;AAC7C,YAAI,CAAC,EAAE,MAAM,CAAC,EAAE,SAAU,SAAQ,KAAK,CAAC;AACxC;AAAA,MACF;AACA;AACE,cAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,cAAM,QAAQ,KAAK,WAAW,IAAI,OAAO,KAAK,WAAW,CAAC,IAAI;AAC9D,cAAM,WAAW,MAAM,GAAG,iBAAiB,KAAK,QAAQ,IAAI,GAAG,EAAE,aAAa,MAAM,CAAC;AACrF,YAAI;AACF,kBAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,SAAS,KAAK,CAAC;AAAA,CAAI;AAAA,QAC5D,UAAE;AACA,mBAAS,QAAQ;AAAA,QACnB;AACA;AAAA,MACF;AAAA,IACF;AAAA,IACA;AACE,UAAI,iBAAiB,IAAI,EAAE;AAAA,EAC/B;AACF;AAEA,KAAK,EAAE,MAAM,CAAC,QAAiB;AAC7B,QAAM,MAAM,eAAe,QAAS,IAAI,SAAS,IAAI,UAAW,OAAO,GAAG;AAC1E,MAAI,GAAG;AACT,CAAC;",
4
+ "sourcesContent": ["#!/usr/bin/env node\n/**\n * pack-manager CLI \u2014 thin wrapper around the pack-manager pure functions\n * so spawnService can call it as a sub-process.\n *\n * node bds-tools/dist/pack-manager.js assemble-bp --src <dir> --out <dir> --name <name> [--uuid <uuid>] [--module-uuid <uuid>] [--version 1,0,0] [--description \"...\"] [--icon <png>]\n * node bds-tools/dist/pack-manager.js assemble-rp (--modules-dir <dir>|--modules-json <file>) --out <dir> --name <name> [--uuid <uuid>] [--module-uuid <uuid>] [--version 1,0,0] [--description \"...\"]\n * node bds-tools/dist/pack-manager.js deploy --bds-root <dir> --level <name> --bp-src <dir> [--rp-src <dir>] --bp-name <name> [--rp-name <name>] [--clear-rp]\n * node bds-tools/dist/pack-manager.js enable-pack --worlds-dir <dir> --level <name> --kind behavior|resource --pack-id <uuid> --version 1,0,0\n * node bds-tools/dist/pack-manager.js disable-pack --worlds-dir <dir> --level <name> --kind behavior|resource --pack-id <uuid>\n * node bds-tools/dist/pack-manager.js ensure-permission --bds-root <dir> --pack-id <uuid>\n * node bds-tools/dist/pack-manager.js read-level --bds-root <dir>\n * node bds-tools/dist/pack-manager.js read-manifest --pack-dir <dir>\n * node bds-tools/dist/pack-manager.js has-pack --worlds-dir <dir> --level <name> --kind behavior|resource --pack-id <uuid>\n * node bds-tools/dist/pack-manager.js list-packs --worlds-dir <dir> --level <name> --kind behavior|resource\n *\n * The pure-function API lives in pack-manager.ts. This CLI exists so a\n * spawnService child process doesn't have to deal with module resolution \u2014\n * it just gets SFMC_ROOT injected, finds its own dist sibling,\n * and reads JSON flags from argv.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { readLevelName } from \"./pack-manager.js\";\nimport type { PackManifestDependency } from \"./dependency-negotiator.js\";\n\nfunction die(msg: string, code = 1): never {\n process.stderr.write(`[pack-manager] ${msg}\\n`);\n process.exit(code);\n}\n\nfunction parseArgs(argv: string[]): { [k: string]: string | undefined } {\n const out: { [k: string]: string | undefined } = {};\n for (let i = 0; i < argv.length; i++) {\n const a = argv[i];\n if (a && a.startsWith(\"--\")) {\n const key = a.slice(2);\n const next = argv[++i];\n /* \u5E03\u5C14\u65D7\u6807(\u65E0\u503C\u6216\u4E0B\u4E00\u53C2\u4E5F\u662F --xxx) */\n if (next === undefined || next.startsWith(\"--\")) {\n out[key] = \"1\";\n if (next !== undefined) i--;\n } else {\n out[key] = next;\n }\n }\n }\n return out;\n}\n\nfunction need(args: { [k: string]: string | undefined }, key: string): string {\n const v = args[key];\n if (!v) die(`--${key} required`);\n return v;\n}\n\nfunction parseVersion(s: string | undefined): [number, number, number] {\n if (!s) return [1, 0, 0];\n const parts = s.split(\",\").map((x) => Number(x.trim()));\n if (parts.length !== 3 || parts.some((n) => !Number.isInteger(n) || (n as number) < 0)) {\n die(`invalid --version (expected \"M,m,p\"): ${s}`);\n }\n return parts as [number, number, number];\n}\n\nasync function main(): Promise<void> {\n const argv = process.argv.slice(2);\n if (argv.length === 0) {\n die(\"usage: pack-manager <verb> [--flags]\");\n }\n const verb = argv[0];\n const args = parseArgs(argv.slice(1));\n\n const mod = await import(\"./pack-manager.js\");\n\n switch (verb) {\n case \"assemble-bp\": {\n const src = need(args, \"src\");\n const out = need(args, \"out\");\n const name = need(args, \"name\");\n const icon = args[\"icon\"];\n let dependencies: PackManifestDependency[] | undefined;\n if (args[\"dependencies-json\"]) {\n try {\n const raw = fs.readFileSync(path.resolve(args[\"dependencies-json\"]), \"utf8\");\n dependencies = JSON.parse(raw);\n } catch {\n /* ignore */\n }\n }\n await mod.assembleBehaviorPack({\n srcDir: path.resolve(src),\n outDir: path.resolve(out),\n projectName: name,\n version: parseVersion(args[\"version\"]),\n description: args[\"description\"],\n ...(icon ? { iconSrc: path.resolve(icon) } : {}),\n ...(args[\"uuid\"] ? { uuid: args[\"uuid\"] } : {}),\n ...(args[\"module-uuid\"] ? { moduleUuid: args[\"module-uuid\"] } : {}),\n ...(dependencies ? { dependencies } : {}),\n });\n process.stdout.write(`[pack-manager] assembled BP at ${out}\\n`);\n return;\n }\n case \"assemble-rp\": {\n const out = need(args, \"out\");\n const name = need(args, \"name\");\n /* OCP:\u663E\u5F0F map \u4F18\u5148;\u5426\u5219\u56DE\u9000\u626B\u63CF --modules-dir */\n let map: Record<string, string>;\n if (args[\"modules-json\"]) {\n map = mod.loadModuleResourcePackMap(path.resolve(args[\"modules-json\"]));\n } else {\n const modulesDir = need(args, \"modules-dir\");\n map = mod.scanModuleResourcePacks(path.resolve(modulesDir));\n }\n await mod.assembleResourcePack({\n moduleResourceDirs: map,\n outDir: path.resolve(out),\n projectName: name,\n version: parseVersion(args[\"version\"]),\n description: args[\"description\"],\n ...(args[\"uuid\"] ? { uuid: args[\"uuid\"] } : {}),\n ...(args[\"module-uuid\"] ? { moduleUuid: args[\"module-uuid\"] } : {}),\n });\n process.stdout.write(`[pack-manager] assembled RP at ${out} (${Object.keys(map).length} modules)\\n`);\n return;\n }\n case \"deploy\": {\n const bdsRoot = need(args, \"bds-root\");\n const level = need(args, \"level\");\n const bpSrc = need(args, \"bp-src\");\n const bpName = need(args, \"bp-name\");\n const rpSrc = args[\"rp-src\"];\n const rpName = args[\"rp-name\"];\n const clearRp = args[\"clear-rp\"] === \"1\" || args[\"clear-rp\"] === \"true\";\n await mod.deployToBDS({\n bdsRoot: path.resolve(bdsRoot),\n levelName: level,\n behaviorPackSrc: path.resolve(bpSrc),\n ...(rpSrc ? { resourcePackSrc: path.resolve(rpSrc) } : {}),\n bpName,\n ...(rpName ? { rpName } : {}),\n ...(clearRp ? { clearResourcePack: true } : {}),\n });\n process.stdout.write(`[pack-manager] deployed to ${mod.bdsWorldLevelDir(path.resolve(bdsRoot), level)}\\n`);\n return;\n }\n case \"enable-pack\": {\n const worldsDir = need(args, \"worlds-dir\");\n const level = need(args, \"level\");\n const kind = need(args, \"kind\") as \"behavior\" | \"resource\";\n const packId = need(args, \"pack-id\");\n await mod.enablePackInWorld({\n worldsDir: path.resolve(worldsDir),\n levelName: level,\n kind,\n packUuid: packId,\n version: parseVersion(args[\"version\"]),\n });\n process.stdout.write(`[pack-manager] enabled ${kind} pack ${packId} in ${level}\\n`);\n return;\n }\n case \"disable-pack\": {\n const worldsDir = need(args, \"worlds-dir\");\n const level = need(args, \"level\");\n const kind = need(args, \"kind\") as \"behavior\" | \"resource\";\n const packId = need(args, \"pack-id\");\n await mod.disablePackInWorld({\n worldsDir: path.resolve(worldsDir),\n levelName: level,\n kind,\n packUuid: packId,\n version: parseVersion(args[\"version\"] ?? \"1,0,0\"),\n });\n process.stdout.write(`[pack-manager] disabled ${kind} pack ${packId} in ${level}\\n`);\n return;\n }\n case \"ensure-permission\": {\n const bdsRoot = need(args, \"bds-root\");\n const packId = need(args, \"pack-id\");\n const root = path.resolve(bdsRoot);\n const wrote = await mod.ensureConfigPermission(root, packId);\n const rel = path.relative(root, mod.configPermissionPath(root, packId));\n process.stdout.write(\n wrote ? `[pack-manager] wrote ${rel}\\n` : `[pack-manager] ${rel} already exists \u2014 skipped\\n`\n );\n return;\n }\n case \"read-level\": {\n const root = need(args, \"bds-root\");\n const name = await readLevelName(path.resolve(root));\n process.stdout.write(`${name}\\n`);\n return;\n }\n case \"read-manifest\": {\n const packDir = need(args, \"pack-dir\");\n const header = mod.readPackManifestHeader(path.resolve(packDir));\n if (!header) {\n process.stdout.write(\"null\\n\");\n return;\n }\n process.stdout.write(`${JSON.stringify(header)}\\n`);\n return;\n }\n case \"has-pack\": {\n const worldsDir = need(args, \"worlds-dir\");\n const level = need(args, \"level\");\n const kind = need(args, \"kind\") as \"behavior\" | \"resource\";\n const packId = need(args, \"pack-id\");\n const ok = mod.worldPackListHas(path.resolve(worldsDir), level, kind, packId);\n process.stdout.write(ok ? \"1\\n\" : \"0\\n\");\n return;\n }\n case \"list-packs\": {\n /* \u6743\u5A01\u4E16\u754C\u6E05\u5355\u8BFB\u53D6 \u2014 \u8C03\u7528\u65B9\u52FF\u518D\u76F4\u63A5\u89E3\u6790 world_*_packs.json(Demeter/DRY) */\n const worldsDir = need(args, \"worlds-dir\");\n const level = need(args, \"level\");\n const kind = need(args, \"kind\") as \"behavior\" | \"resource\";\n const list = mod.readWorldPackList(path.resolve(worldsDir), level, kind);\n process.stdout.write(`${JSON.stringify(list)}\\n`);\n return;\n }\n case \"list-installed\":\n case \"bump-version\":\n case \"install-dir\":\n case \"discover-packs\": {\n /* OCP: world-packs \u52A8\u8BCD\u8868\u6269\u5C55\uFF0C\u907F\u514D\u6BCF case \u91CD\u590D dynamic import\uFF08DRY\uFF09 */\n const wp = await import(\"./world-packs.js\");\n if (verb === \"list-installed\") {\n const bdsRoot = need(args, \"bds-root\");\n const level = need(args, \"level\");\n const list = wp.listInstalledWorldPacks(path.resolve(bdsRoot), level);\n process.stdout.write(`${JSON.stringify(list)}\\n`);\n return;\n }\n if (verb === \"bump-version\") {\n const packDir = need(args, \"pack-dir\");\n const next = wp.bumpPackPatchVersion(path.resolve(packDir));\n process.stdout.write(`${JSON.stringify({ version: next })}\\n`);\n return;\n }\n if (verb === \"install-dir\") {\n const src = need(args, \"src\");\n const destParent = need(args, \"dest-parent\");\n const force = !!args[\"force\"];\n const r = await wp.installPackDirectory({\n srcDir: path.resolve(src),\n destParent: path.resolve(destParent),\n force,\n ...(args[\"folder-name\"] ? { folderName: args[\"folder-name\"] } : {}),\n });\n process.stdout.write(`${JSON.stringify(r)}\\n`);\n if (!r.ok && !r.conflict) process.exit(1);\n return;\n }\n {\n const root = need(args, \"root\");\n const depth = args[\"max-depth\"] ? Number(args[\"max-depth\"]) : 4;\n const resolved = await wp.resolvePackRoots(path.resolve(root), { maxDirDepth: depth });\n try {\n process.stdout.write(`${JSON.stringify(resolved.roots)}\\n`);\n } finally {\n resolved.dispose();\n }\n return;\n }\n }\n default:\n die(`unknown verb: ${verb}`);\n }\n}\n\nmain().catch((err: unknown) => {\n const msg = err instanceof Error ? (err.stack ?? err.message) : String(err);\n die(msg);\n});\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * dependency-negotiator.ts — Bedrock 原生模块依赖版本解析与动态协商器
3
+ *
4
+ * 职责:
5
+ * 1. Bedrock 原生模块版本(SemVer / Beta / Preview)对比算法;
6
+ * 2. 聚合平台默认基准依赖与各业务模块声明的 Minecraft 依赖需求;
7
+ * 3. 动态提升聚合行为包 manifest.json 中的 dependencies;
8
+ * 4. 判定协商后是否包含需要存档开启测试版玩法(Beta APIs / gametest)的模块。
9
+ */
10
+ export interface PackManifestDependency {
11
+ module_name?: string | undefined;
12
+ version?: string | number[] | undefined;
13
+ uuid?: string | undefined;
14
+ }
15
+ export interface ModuleDeclaredDependencies {
16
+ folderId: string;
17
+ dependencies: PackManifestDependency[];
18
+ }
19
+ export interface DependencyPromotion {
20
+ moduleName: string;
21
+ from: string;
22
+ to: string;
23
+ requestedBy: string[];
24
+ }
25
+ export interface NegotiatedDependenciesResult {
26
+ /** 协商完成后的最终 dependencies 列表 */
27
+ dependencies: PackManifestDependency[];
28
+ /** 本次协商发生的版本提升记录(便于日志展示) */
29
+ promotions: DependencyPromotion[];
30
+ /** 是否引入了需要 level.dat 开启 Beta APIs (gametest = 1b) 的模块 */
31
+ hasBetaApis: boolean;
32
+ }
33
+ /** Bedrock 引擎原生内置的 Script API 模块集合(排除纯 npm 类型/数据包如 vanilla-data, math) */
34
+ export declare const NATIVE_BEDROCK_SCRIPT_MODULES: Set<string>;
35
+ /** SFMC 平台合成 BP 的默认基准依赖(稳定保底) */
36
+ export declare const BASELINE_BEDROCK_DEPENDENCIES: PackManifestDependency[];
37
+ /**
38
+ * 清理并规范化版本号字符串(去除 npm range 前缀,如 `^2.0.0-beta` → `2.0.0-beta`)。
39
+ */
40
+ export declare function cleanBedrockVersion(raw: string | number[] | undefined): string;
41
+ /**
42
+ * 比较两个 Bedrock 版本号:
43
+ * a > b 返回正数;a < b 返回负数;a === b 返回 0。
44
+ *
45
+ * 核心规则:
46
+ * 1. "beta" 为预览/测试轨顶级,高于任何纯数字稳定版;
47
+ * 2. 优先比较 major, minor, patch 数字;
48
+ * 3. 在同一大版本或低版本下:
49
+ * - 若 majorA > majorB(例如 2.0.0 vs 1.3.0),major 高者胜出;
50
+ * - 若 major/minor/patch 均相同,正式版优先于 prerelease;
51
+ * - 若两者均为 prerelease,按字典序比较。
52
+ */
53
+ export declare function compareBedrockVersion(a: string, b: string): number;
54
+ /**
55
+ * 判定一个依赖项是否真正需要世界存档开启测试版玩法(Beta APIs / gametest)。
56
+ * 注意:@minecraft/server-net 与 @minecraft/server-admin 虽带 -beta,但属于 permissions.json 模块权限,
57
+ * 不需要 level.dat 的 gametest 实验开关。
58
+ */
59
+ export declare function isGametestBetaRequired(dep: PackManifestDependency): boolean;
60
+ /**
61
+ * 动态协商 Bedrock 原生模块依赖。
62
+ *
63
+ * 算法:
64
+ * 1. 以 baseline 为基准建立模块索引表;
65
+ * 2. 遍历所有已启用模块声明的 dependencies;
66
+ * 3. 若模块对某原生模块提出了更高的版本需求,动态提升(promote)该依赖的版本,并记录提议模组;
67
+ * 4. 统计是否引入了需要测试玩法的 Beta API。
68
+ *
69
+ * @param baseline 基准依赖列表(缺省使用 BASELINE_BEDROCK_DEPENDENCIES)
70
+ * @param moduleRequirements 各已启用模块声明的依赖项列表
71
+ */
72
+ export declare function negotiateBedrockDependencies(baseline?: PackManifestDependency[], moduleRequirements?: ModuleDeclaredDependencies[]): NegotiatedDependenciesResult;
73
+ //# sourceMappingURL=dependency-negotiator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-negotiator.d.ts","sourceRoot":"","sources":["../src/dependency-negotiator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,sBAAsB,EAAE,CAAC;CACxC;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,4BAA4B;IAC3C,+BAA+B;IAC/B,YAAY,EAAE,sBAAsB,EAAE,CAAC;IACvC,4BAA4B;IAC5B,UAAU,EAAE,mBAAmB,EAAE,CAAC;IAClC,yDAAyD;IACzD,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,0EAA0E;AAC1E,eAAO,MAAM,6BAA6B,aAWxC,CAAC;AAEH,iCAAiC;AACjC,eAAO,MAAM,6BAA6B,EAAE,sBAAsB,EAMjE,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,CAa9E;AAuBD;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAuBlE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,sBAAsB,GAAG,OAAO,CAS3E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,GAAE,sBAAsB,EAAkC,EAClE,kBAAkB,GAAE,0BAA0B,EAAO,GACpD,4BAA4B,CAyF9B"}